Recode Data
Arab3
arab3 %<>%
mutate(cntry = sjmisc::to_label(country)) %>%
mutate(region = sjmisc::to_label(a1)) %>%
mutate(governorate = sjmisc::to_label(q1)) %>%
mutate(year = lubridate::year(date))
# Dependent Variable
arab3 %<>%
mutate(islamistparties1 = ifelse(q518a2 > 5, NA, 5 - q518a2)) %>%
mutate(islamistparties2 = ifelse(q518b2 > 5, NA, 5 - q518b2)) %>%
mutate(islamistparties = case_when(
islamistparties1 == 1 ~ 1,
islamistparties1 == 2 ~ 2,
islamistparties1 == 3 ~ 3,
islamistparties1 == 4 ~ 4,
islamistparties2 == 1 ~ 1,
islamistparties2 == 2 ~ 2,
islamistparties2 == 3 ~ 3,
islamistparties2 == 4 ~ 4)
) %>%
mutate(islamistgov = ifelse(q5184 > 5, NA, 5 - q5184)) %>%
mutate(religinterfere = ifelse(q6061 > 5, NA, q6061)) %>%
mutate(religleaders = ifelse(q6062 > 5, NA, 5 - q6062)) %>%
mutate(religleadersinfl = ifelse(q6063 > 5, NA, 5 - q6063)) %>%
mutate(seperation = ifelse(q6064 > 5, NA, q6064)) %>%
mutate(religparty = Recode(q605a, "1 = 1;
2 = 1;
3 = 0;
4 = 0;
5 = 0;
8 = 0;
9 = NA")) %>%
mutate(religparty2 = Recode(q605a, "1 = 5;
2 = 4;
3 = 2;
4 = 1;
5 = 3;
8 = NA;
9 = NA"))
ifelse4cat_rec <- function(variable) {
recoded <- ifelse(variable == 0 | variable > 5, NA, 5 - variable)
return(recoded)
}
arab3 %<>%
mutate(female = ifelse(sex == 2, 1, 0)) %>%
mutate(work = ifelse(q1004 == 0 | q1004 > 5, NA, abs(q1004 - 2))) %>%
mutate(income = ifelse4cat_rec(q1016)) %>%
mutate(age = ifelse(q1001 == 0 | q1001 == 9999, NA, q1001)) %>%
mutate(educ = case_when(
q1003 == 0 ~ NA_real_,
q1003 == 99 ~ NA_real_,
q1003 == 5 ~ 4,
q1003 == 6 ~ 5,
q1003 == 7 ~ 6,
q1003yem == 0 ~ NA_real_,
q1003yem == 99 ~ NA_real_,
q1003yem == 4 ~ 3,
q1003yem == 5 ~ 4,
q1003yem == 6 ~ 5,
q1003yem == 7 ~ 5,
q1003yem == 8 ~ 6,
q1003t == 0 ~ NA_real_,
q1003t == 99 ~ NA_real_,
q1003t == 1 ~ 1,
q1003t == 2 ~ 2,
q1003t == 3 ~ 3,
q1003t == 4 ~ 4,
q1003t == 5 ~ 5,
q1003t == 6 ~ 6,
TRUE ~ as.numeric(q1003))
) %>%
mutate(globalism = ifelse(q701b == 0 | q701b > 5, NA, q701b)) %>%
mutate(pray = ifelse(q6101 == 0 | q6101 > 5, NA, 6 - q6101)) %>%
mutate(quran = ifelse(q6106 == 0 | q6106 > 5, NA, 6 - q6106)) %>%
mutate(womanwork = ifelse(q6012 == 0 | q6012 > 5, NA, q6012)) %>%
mutate(womenleader = ifelse4cat_rec(q6013)) %>%
mutate(womeneduc = ifelse4cat_rec(q6014)) %>%
mutate(nodemoc = ifelse(q6071 == 0 | q6071 > 5, NA, q6071)) %>%
mutate(genderapartuni = ifelse4cat_rec(q6074)) %>%
mutate(coverup = ifelse4cat_rec(q6076)) %>%
select(cntry, year, region, governorate, islamistparties , islamistgov, religinterfere, religleaders, religleadersinfl, seperation, religparty, religparty2, female, work, income, age, educ, globalism, pray, quran, womanwork, womenleader, womeneduc, nodemoc, genderapartuni, coverup)
Arab4
table(arab4$country)
1 5 8 10 13 15 21
1199 1146 1172 615 1199 1177 1200
arab4 %<>%
mutate(cntry = sjmisc::to_label(country)) %>%
mutate(region = sjmisc::to_label(a1)) %>%
mutate(governorate = sjmisc::to_label(q1)) %>%
mutate(year = 2016)#%>%
# mutate(district = sjmisc::to_label(q2))
# Dependent Variable
arab4 %<>%
mutate(islamistparties = ifelse(q5182 > 5, NA, 5 - q5182)) %>%
mutate(islamistgov = ifelse(q5184 > 5, NA, 5 - q5184)) %>%
mutate(religinterfere = ifelse(q6061 > 5, NA, q6061)) %>%
mutate(religleaders = ifelse(q6062 > 5, NA, 5 - q6062)) %>%
mutate(religleadersinfl = ifelse(q6063 > 5, NA, 5 - q6063)) %>%
mutate(seperation = ifelse(q6064 > 5, NA, q6064)) %>%
mutate(religparty = Recode(q605a, "1 = 1;
2 = 1;
3 = 0;
4 = 0;
5 = 0;
98 = 0;
99 = NA")) %>%
mutate(religparty2 = Recode(q605a, "1 = 5;
2 = 4;
3 = 2;
4 = 1;
5 = 3;
98 = NA;
99 = NA"))
arab4 %<>%
mutate(female = ifelse(q1002 == 2, 1, 0)) %>%
mutate(work = ifelse(q1004 == 0 | q1004 > 5, NA, abs(q1004 - 2))) %>%
mutate(income = ifelse4cat_rec(q1016)) %>%
mutate(age = ifelse(q1001 == 0 | q1001 == 9999, NA, q1001)) %>%
mutate(educ = case_when(
q1003 == 0 ~ NA_real_,
q1003 == 98 ~ NA_real_,
q1003 == 99 ~ NA_real_,
q1003 == 5 ~ 4,
q1003 == 6 ~ 5,
q1003 == 7 ~ 6,
t1003 == 0 ~ NA_real_,
t1003 == 98 ~ NA_real_,
t1003 == 99 ~ NA_real_,
t1003 == 3 ~ 3,
t1003 == 4 ~ 4,
t1003 == 5 ~ 5,
t1003 == 6 ~ 6,
TRUE ~ as.numeric(q1003))
) %>%
mutate(globalism = ifelse(q701b == 0 | q701b > 5, NA, q701b)) %>%
mutate(pray = ifelse(q6101 == 0 | q6101 > 5, NA, 6 - q6101)) %>%
mutate(quran = ifelse(q6106 == 0 | q6106 > 5, NA, 6 - q6106)) %>%
mutate(womanwork = ifelse(q6012 == 0 | q6012 > 5, NA, q6012)) %>%
mutate(womenleader = ifelse4cat_rec(q6013)) %>%
mutate(womeneduc = ifelse4cat_rec(q6014)) %>%
mutate(nodemoc = ifelse(q6071 == 0 | q6071 > 5, NA, q6071)) %>%
mutate(genderapartuni = ifelse4cat_rec(q6074)) %>%
mutate(coverup = ifelse4cat_rec(q6076)) %>%
select(cntry, year, region, governorate , islamistparties , islamistgov, religinterfere, religleaders, religleadersinfl, seperation, religparty, religparty2, female, work, income, age, educ, globalism, pray, quran, womanwork, womenleader, womeneduc, nodemoc, genderapartuni, coverup)
Factor Analysis
# f1 <- arab %>%
# select(islamistparties, islamistgov,
# religleaders, religleadersinfl) %>%
# # na.omit() %>%
# psych::fa(1, rotate = "varimax",
# fm = "pa",
# scores = "regression",
# weight = na.omit(arab$wt) )
# fa.diagram(f1)
# f1
f2 <- arab %>%
select(islamistparties, islamistgov,
religleaders, religleadersinfl) %>%
psych::pca(weight = arab$wt)
arab %>%
select(islamistparties, islamistgov,
religleaders, religleadersinfl) %>%
alpha()
Reliability analysis
Call: alpha(x = .)
raw_alpha std.alpha G6(smc) average_r S/N ase mean sd
0.7 0.7 0.66 0.37 2.3 0.0034 2 0.71
lower alpha upper 95% confidence boundaries
0.69 0.7 0.71
Reliability if an item is dropped:
raw_alpha std.alpha G6(smc) average_r S/N alpha se
islamistparties 0.65 0.65 0.58 0.39 1.9 0.0042
islamistgov 0.65 0.66 0.58 0.39 1.9 0.0041
religleaders 0.60 0.60 0.51 0.33 1.5 0.0046
religleadersinfl 0.64 0.64 0.54 0.37 1.7 0.0042
Item statistics
n raw.r std.r r.cor r.drop mean sd
islamistparties 20198 0.72 0.71 0.55 0.46 1.7 0.95
islamistgov 20135 0.73 0.71 0.54 0.46 1.7 1.02
religleaders 20431 0.75 0.76 0.66 0.53 2.3 0.92
religleadersinfl 20524 0.72 0.73 0.60 0.48 2.2 0.89
Non missing response frequency for each item
1 2 3 4 5 miss
islamistparties 0.59 0.19 0.15 0.07 0 0.08
islamistgov 0.59 0.17 0.14 0.10 0 0.08
religleaders 0.21 0.38 0.31 0.10 0 0.07
religleadersinfl 0.24 0.42 0.26 0.08 0 0.06
arab %>%
select(islamistparties, islamistgov,
religleaders, religleadersinfl) %>%
KMO()
Kaiser-Meyer-Olkin factor adequacy
Call: KMO(r = .)
Overall MSA = 0.68
MSA for each item =
islamistparties islamistgov religleaders religleadersinfl
0.71 0.72 0.66 0.66
arab4 %>%
select(islamistparties, islamistgov,
religleaders, religleadersinfl,
religparty2, seperation,
religinterfere) %>%
na.omit() %>%
cor()
islamistparties islamistgov religleaders religleadersinfl
islamistparties 1.0000000 0.3760955 0.3274069 0.2595854
islamistgov 0.3760955 1.0000000 0.3180997 0.3059820
religleaders 0.3274069 0.3180997 1.0000000 0.5628358
religleadersinfl 0.2595854 0.3059820 0.5628358 1.0000000
religparty2 0.2625742 0.2409189 0.3812004 0.3120300
seperation 0.1409401 0.2186956 0.3190967 0.2944263
religinterfere 0.1393481 0.1283822 0.2070613 0.2539891
religparty2 seperation religinterfere
islamistparties 0.2625742 0.1409401 0.1393481
islamistgov 0.2409189 0.2186956 0.1283822
religleaders 0.3812004 0.3190967 0.2070613
religleadersinfl 0.3120300 0.2944263 0.2539891
religparty2 1.0000000 0.2819491 0.1671423
seperation 0.2819491 1.0000000 0.2725233
religinterfere 0.1671423 0.2725233 1.0000000
# arab <- predict.psych(f1, arab %>%
# select(islamistparties, islamistgov,
# religleaders, religleadersinfl)) %>%
# tbl_df() %>%
# cbind(arab) %>%
# mutate(islamism_fa = PA1)
arab <- predict.psych(f2, arab %>%
select(islamistparties, islamistgov,
religleaders, religleadersinfl)) %>%
tbl_df() %>%
transmute(islamism = PC1) %>%
cbind(arab)
#%>%
# ggplot(aes(islamism)) +
# geom_histogram() +
# facet_wrap(~cntry, scales = "free")
#sjPlot::view_df(arab, show.frq = T, show.prc = T)
#
# cor.test(arab$PC1, arab$PA1)
Regression
model1 <- lme4::lmer(islamism ~ female + work + income + age + educ + globalism + antiwestern + personalpiety + patriarchalvalues + liberalislam + year_2012 + year_2013 + year_2014 + (1|cntry), data = arab_reg, weights = wt)
texreg::screenreg(model1)
=====================================
Model 1
-------------------------------------
(Intercept) -0.18
(0.11)
female 0.07 ***
(0.02)
work -0.06 ***
(0.02)
income 0.00
(0.01)
age -0.00 ***
(0.00)
educ -0.03 ***
(0.01)
globalism 0.08 ***
(0.01)
antiwestern -0.06 *
(0.03)
personalpiety 0.54 ***
(0.04)
patriarchalvalues 0.76 ***
(0.04)
liberalislam -1.04 ***
(0.04)
year_2012 0.00
(0.04)
year_2013 0.18 ***
(0.02)
year_2014 -0.08
(0.09)
-------------------------------------
AIC 33078.64
BIC 33197.69
Log Likelihood -16523.32
Num. obs. 12591
Num. groups: cntry 12
Var: cntry (Intercept) 0.10
Var: Residual 0.69
=====================================
*** p < 0.001, ** p < 0.01, * p < 0.05
model1 <- arab_reg %>%
lme4::lmer(islamism ~ female + work + income + age + educ + globalism + pray + quran + womanwork + womenleader + womeneduc + nodemoc + genderapartuni + coverup + (1|cntry/year), data = .)
texreg::screenreg(model1)
==========================================
Model 1
------------------------------------------
(Intercept) 33.38 ***
(2.54)
female 1.89 ***
(0.38)
work -1.31 ***
(0.38)
income 0.28
(0.18)
age -1.02 ***
(0.19)
educ -0.74 ***
(0.20)
globalism 1.63 ***
(0.18)
pray 1.31 ***
(0.20)
quran 2.05 ***
(0.19)
womanwork 0.78 ***
(0.22)
womenleader 2.40 ***
(0.18)
womeneduc 2.14 ***
(0.20)
nodemoc -3.63 ***
(0.21)
genderapartuni -4.56 ***
(0.22)
coverup -0.82 ***
(0.18)
------------------------------------------
AIC 118239.29
BIC 118374.48
Log Likelihood -59101.64
Num. obs. 13499
Num. groups: year:cntry 19
Num. groups: cntry 12
Var: year:cntry (Intercept) 14.12
Var: cntry (Intercept) 37.00
Var: Residual 369.66
==========================================
*** p < 0.001, ** p < 0.01, * p < 0.05
plot_model(model1, sort.est = T, show.values = T, show.p = T, value.offset = 0.5)
Computing p-values via Wald-statistics approximation (treating t as Wald z).

plot_model(model1, terms = c("nodemoc", "female"), type = "pred")
Note: uncertainty of the random effects parameters are not taken into account for confidence intervals.

model2 <- arab_reg %>%
lme4::lmer(islamism ~ female + work + income + age + educ + globalism + pray + quran + womanwork + womenleader + womeneduc + nodemoc + genderapartuni + coverup + nodemoc*quran + (1|cntry/year), data = .)
texreg::screenreg(model2)
==========================================
Model 1
------------------------------------------
(Intercept) 35.34 ***
(3.22)
female 1.89 ***
(0.38)
work -1.31 ***
(0.38)
income 0.28
(0.18)
age -1.02 ***
(0.19)
educ -0.74 ***
(0.20)
globalism 1.63 ***
(0.18)
pray 1.32 ***
(0.20)
quran 1.53 **
(0.56)
womanwork 0.79 ***
(0.22)
womenleader 2.40 ***
(0.18)
womeneduc 2.14 ***
(0.20)
nodemoc -4.32 ***
(0.72)
genderapartuni -4.55 ***
(0.22)
coverup -0.82 ***
(0.18)
quran:nodemoc 0.18
(0.18)
------------------------------------------
AIC 118241.91
BIC 118384.60
Log Likelihood -59101.95
Num. obs. 13499
Num. groups: year:cntry 19
Num. groups: cntry 12
Var: year:cntry (Intercept) 14.13
Var: cntry (Intercept) 37.02
Var: Residual 369.66
==========================================
*** p < 0.001, ** p < 0.01, * p < 0.05
view_df2 <- function (x, weight.by = NULL, altr.row.col = TRUE, show.id = TRUE,
show.type = FALSE, show.values = TRUE, show.string.values = FALSE,
show.labels = TRUE, show.frq = FALSE, show.prc = FALSE,
show.wtd.frq = FALSE, show.wtd.prc = FALSE, show.na = FALSE,
max.len = 15, sort.by.name = FALSE, wrap.labels = 50, hide.progress = FALSE,
CSS = NULL, encoding = NULL, file = NULL, use.viewer = TRUE,
no.output = FALSE, remove.spaces = TRUE)
{
get.encoding <- function(encoding, data = NULL) {
if (is.null(encoding)) {
if (!is.null(data) && is.data.frame(data)) {
# get variable label
labs <- sjlabelled::get_label(data[[1]])
# check if vectors of data frame have
# any valid label. else, default to utf-8
if (!is.null(labs) && is.character(labs))
encoding <- Encoding(sjlabelled::get_label(data[[1]]))
else
encoding <- "UTF-8"
# unknown encoding? default to utf-8
if (encoding == "unknown") encoding <- "UTF-8"
} else if (.Platform$OS.type == "unix")
encoding <- "UTF-8"
else
encoding <- "Windows-1252"
}
return(encoding)
}
has_value_labels <- function(x) {
!(is.null(attr(x, "labels", exact = T)) && is.null(attr(x, "value.labels", exact = T)))
}
sju.rmspc <- function(html.table) {
cleaned <- gsub(" <", "<", html.table, fixed = TRUE, useBytes = TRUE)
cleaned <- gsub(" <", "<", cleaned, fixed = TRUE, useBytes = TRUE)
cleaned <- gsub(" <", "<", cleaned, fixed = TRUE, useBytes = TRUE)
return(cleaned)
}
frq.value <- function(index, x, df.val, weights = NULL) {
valstring <- ""
# check if we have a valid index
if (index <= ncol(x) && !is.null(df.val[[index]])) {
# do we have weights?
if (!is.null(weights))
variab <- sjstats::weight(x[[index]], weights)
else
variab <- x[[index]]
# create frequency table. same function as for
# sjt.frq and sjp.frq
ftab <- create.frq.df(variab, 20)$mydat$frq
# remove last value, which is N for NA
if (length(ftab) == 1 && is.na(ftab)) {
valstring <- "<NA>"
} else {
for (i in 1:(length(ftab) - 1)) {
valstring <- paste0(valstring, ftab[i])
if (i < length(ftab)) valstring <- paste0(valstring, "<br>")
}
}
} else {
valstring <- ""
}
return(valstring)
}
prc.value <- function(index, x, df.val, weights = NULL) {
valstring <- ""
# check for valid indices
if (index <= ncol(x) && !is.null(df.val[[index]])) {
# do we have weights?
if (!is.null(weights))
variab <- sjstats::weight(x[[index]], weights)
else
variab <- x[[index]]
# create frequency table, but only get valid percentages
ftab <- create.frq.df(variab, 20)$mydat$valid.prc
# remove last value, which is a NA dummy
if (length(ftab) == 1 && is.na(ftab)) {
valstring <- "<NA>"
} else {
for (i in 1:(length(ftab) - 1)) {
valstring <- paste0(valstring, sprintf("%.2f", ftab[i]))
if (i < length(ftab)) valstring <- paste0(valstring, "<br>")
}
}
} else {
valstring <- ""
}
return(valstring)
}
encoding <- get.encoding(encoding, x)
if (!is.data.frame(x))
stop("Parameter needs to be a data frame!", call. = FALSE)
df.var <- sjlabelled::get_label(x)
df.val <- sjlabelled::get_labels(x)
colcnt <- ncol(x)
id <- seq_len(colcnt)
if (sort.by.name)
id <- id[order(colnames(x))]
tag.table <- "table"
tag.thead <- "thead"
tag.tdata <- "tdata"
tag.arc <- "arc"
tag.caption <- "caption"
tag.omit <- "omit"
css.table <- "border-collapse:collapse; border:none;"
css.thead <- "border-bottom:double; font-style:italic; font-weight:normal; padding:0.2cm; text-align:left; vertical-align:top;"
css.tdata <- "padding:0.2cm; text-align:left; vertical-align:top;"
css.arc <- "background-color:#eeeeee"
css.caption <- "font-weight: bold; text-align:left;"
css.omit <- "color:#999999;"
if (!is.null(CSS)) {
if (!is.null(CSS[["css.table"]]))
css.table <- ifelse(substring(CSS[["css.table"]],
1, 1) == "+", paste0(css.table, substring(CSS[["css.table"]],
2)), CSS[["css.table"]])
if (!is.null(CSS[["css.thead"]]))
css.thead <- ifelse(substring(CSS[["css.thead"]],
1, 1) == "+", paste0(css.thead, substring(CSS[["css.thead"]],
2)), CSS[["css.thead"]])
if (!is.null(CSS[["css.tdata"]]))
css.tdata <- ifelse(substring(CSS[["css.tdata"]],
1, 1) == "+", paste0(css.tdata, substring(CSS[["css.tdata"]],
2)), CSS[["css.tdata"]])
if (!is.null(CSS[["css.arc"]]))
css.arc <- ifelse(substring(CSS[["css.arc"]], 1,
1) == "+", paste0(css.arc, substring(CSS[["css.arc"]],
2)), CSS[["css.arc"]])
if (!is.null(CSS[["css.caption"]]))
css.caption <- ifelse(substring(CSS[["css.caption"]],
1, 1) == "+", paste0(css.caption, substring(CSS[["css.caption"]],
2)), CSS[["css.caption"]])
if (!is.null(CSS[["css.omit"]]))
css.omit <- ifelse(substring(CSS[["css.omit"]],
1, 1) == "+", paste0(css.omit, substring(CSS[["css.omit"]],
2)), CSS[["css.omit"]])
}
page.style <- sprintf("<style>\nhtml, body { background-color: white; }\n%s { %s }\n.%s { %s }\n.%s { %s }\n.%s { %s }\n%s { %s }\n.%s { %s }\n</style>",
tag.table, css.table, tag.thead, css.thead, tag.tdata,
css.tdata, tag.arc, css.arc, tag.caption, css.caption,
tag.omit, css.omit)
toWrite <- sprintf("<html>\n<head>\n<meta http-equiv=\"Content-type\" content=\"text/html;charset=%s\">\n%s\n</head>\n<body>\n",
encoding, page.style)
page.content <- sprintf("<table>\n <caption>Data frame: %s</caption>\n",
deparse(substitute(x)))
page.content <- paste0(page.content, " <tr>\n ")
if (show.id)
page.content <- paste0(page.content, "<th class=\"thead\">ID</th>")
page.content <- paste0(page.content, "<th class=\"thead\">Name</th>")
if (show.type)
page.content <- paste0(page.content, "<th class=\"thead\">Type</th>")
page.content <- paste0(page.content, "<th class=\"thead\">Label</th>")
if (show.na)
page.content <- paste0(page.content, "<th class=\"thead\">missings</th>")
if (show.values)
page.content <- paste0(page.content, "<th class=\"thead\">Values</th>")
if (show.labels)
page.content <- paste0(page.content, "<th class=\"thead\">Value Labels</th>")
if (show.frq)
page.content <- paste0(page.content, "<th class=\"thead\">Freq.</th>")
if (show.prc)
page.content <- paste0(page.content, "<th class=\"thead\">%</th>")
if (show.wtd.frq)
page.content <- paste0(page.content, "<th class=\"thead\">weighted Freq.</th>")
if (show.wtd.prc)
page.content <- paste0(page.content, "<th class=\"thead\">weighted %</th>")
page.content <- paste0(page.content, "\n </tr>\n")
if (!hide.progress)
pb <- utils::txtProgressBar(min = 0, max = colcnt, style = 3)
for (ccnt in seq_len(colcnt)) {
index <- id[ccnt]
arcstring <- ""
if (altr.row.col)
arcstring <- ifelse(sjmisc::is_even(ccnt), " arc",
"")
page.content <- paste0(page.content, " <tr>\n")
if (show.id)
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%i</td>\n",
arcstring, index))
if (!is.list(x[[index]]) && !is.null(sjlabelled::get_note(x[[index]])))
td.title.tag <- sprintf(" title=\"%s\"", sjlabelled::get_note(x[[index]]))
else td.title.tag <- ""
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\"%s>%s</td>\n",
arcstring, td.title.tag, colnames(x)[index]))
if (show.type) {
vartype <- sjmisc::var_type(x[[index]])
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%s</td>\n",
arcstring, vartype))
}
if (index <= length(df.var)) {
varlab <- df.var[index]
if (!is.null(wrap.labels)) {
varlab <- sjmisc::word_wrap(varlab, wrap.labels,
"<br>")
}
}
else {
varlab <- "<NA>"
}
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%s</td>\n",
arcstring, varlab))
if (show.na) {
if (is.list(x[[index]])) {
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\"><span class=\"omit\"><list></span></td>\n",
arcstring))
}
else {
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%i (%.2f%%)</td>\n",
arcstring, sum(is.na(x[[index]]), na.rm = T),
100 * sum(is.na(x[[index]]), na.rm = T)/nrow(x)))
}
}
if (is.numeric(x[[index]]) && !has_value_labels(x[[index]])) {
if (show.values || show.labels) {
valstring <- paste0(sprintf("%a", range(x[[index]],
na.rm = T)), collapse = "-")
if (show.values && show.labels) {
colsp <- " colspan=\"2\""
valstring <- paste0("<em>range: ", valstring,
"</em>")
}
else {
colsp <- ""
}
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\"%s>%s</td>\n",
arcstring, colsp, valstring))
}
}
else {
if (show.values) {
valstring <- ""
if (index <= ncol(x)) {
if (is.list(x[[index]])) {
valstring <- "<span class=\"omit\"><list></span>"
}
else {
vals <- sjlabelled::get_values(x[[index]])
if (!is.null(vals)) {
loop <- na.omit(seq_len(length(vals))[1:max.len])
for (i in loop) {
valstring <- paste0(valstring, vals[i])
if (i < length(vals))
valstring <- paste0(valstring, "<br>")
}
if (max.len < length(vals))
valstring <- paste0(valstring, "<span class=\"omit\"><...></span>")
}
}
}
else {
valstring <- "<NA>"
}
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%s</td>\n",
arcstring, valstring))
}
if (show.labels) {
valstring <- ""
if (index <= length(df.val)) {
if (is.list(x[[index]])) {
valstring <- "<span class=\"omit\"><list></span>"
}
else {
vals <- df.val[[index]]
if (!is.null(vals))
vals <- na.omit(vals)
if (is.character(x[[index]]) && !is.null(vals) &&
!sjmisc::is_empty(vals)) {
if (show.string.values)
vals <- sort(vals)
else vals <- "<span class=\"omit\" title =\"'show.string.values = TRUE' to show values.\"><output omitted></span>"
}
if (!is.null(vals)) {
loop <- na.omit(seq_len(length(vals))[1:max.len])
for (i in loop) {
valstring <- paste0(valstring, vals[i])
if (i < length(vals))
valstring <- paste0(valstring, "<br>")
}
if (max.len < length(vals))
valstring <- paste0(valstring, "<span class=\"omit\"><... truncated></span>")
}
}
}
else {
valstring <- "<NA>"
}
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%s</td>\n",
arcstring, valstring))
}
}
if (show.frq) {
if (is.list(x[[index]]))
valstring <- "<span class=\"omit\"><list></span>"
else valstring <- frq.value(index, x, df.val)
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%s</td>\n",
arcstring, valstring))
}
if (show.prc) {
if (is.list(x[[index]]))
valstring <- "<span class=\"omit\"><list></span>"
else valstring <- prc.value(index, x, df.val)
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%s</td>\n",
arcstring, valstring))
}
if (show.wtd.frq && !is.null(weight.by)) {
if (is.list(x[[index]]))
valstring <- "<span class=\"omit\"><list></span>"
else valstring <- frq.value(index, x, df.val, weight.by)
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%s</td>\n",
arcstring, valstring))
}
if (show.prc && !is.null(weight.by)) {
if (is.list(x[[index]]))
valstring <- "<span class=\"omit\"><list></span>"
else valstring <- prc.value(index, x, df.val, weight.by)
page.content <- paste0(page.content, sprintf(" <td class=\"tdata%s\">%s</td>\n",
arcstring, valstring))
}
if (!hide.progress)
utils::setTxtProgressBar(pb, ccnt)
page.content <- paste0(page.content, " </tr>\n")
}
if (!hide.progress)
close(pb)
page.content <- paste(page.content, "</table>", sep = "\n")
toWrite <- paste0(toWrite, sprintf("%s\n</body></html>",
page.content))
knitr <- page.content
knitr <- gsub("class=", "style=", knitr, fixed = TRUE, useBytes = TRUE)
knitr <- gsub("<table", sprintf("<table style=\"%s\"", css.table),
knitr, fixed = TRUE, useBytes = TRUE)
knitr <- gsub(tag.tdata, css.tdata, knitr, fixed = TRUE,
useBytes = TRUE)
knitr <- gsub(tag.thead, css.thead, knitr, fixed = TRUE,
useBytes = TRUE)
knitr <- gsub(tag.arc, css.arc, knitr, fixed = TRUE, useBytes = TRUE)
if (remove.spaces) {
knitr <- sju.rmspc(knitr)
toWrite <- sju.rmspc(toWrite)
page.content <- sju.rmspc(page.content)
}
structure(class = c("sjTable", "view_df"), list(page.style = page.style,
page.content = page.content, output.complete = toWrite,
header = NULL, knitr = knitr, file = file, show = !no.output,
use.viewer = use.viewer))
}
view_df2(arab4, hide.progress = T)
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojVE9ETyANCiAtIFRleHQga8O8cnplbg0KIC0gUmVwcm9kdWNlIFBsb3RzDQogLSBEbyBhIE1hcCAoTWFwcyBhcmUgYWx3YXMgaW1wb3J0YW50ISkNCiAtIFBDQSBiZXNjaHJlaWJlbg0KDQpgYGB7cn0NCiNwYWNtYW46OnBfaW5zdGFsbF9naCgic3lzdGF0cy9iaW5vY3VsYVIiKQ0KI2RldnRvb2xzOjppbnN0YWxsX2dpdGh1Yigic3RyZW5nZWphY2tlL3NqbGFiZWxsZWQiLGRlcGVuZGVuY2llcz1UUlVFKQ0KI2RldnRvb2xzOjppbnN0YWxsX2dpdGh1Yigic3RyZW5nZWphY2tlL3NqbWlzYyIsZGVwZW5kZW5jaWVzPVRSVUUpDQojZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJzdHJlbmdlamFja2Uvc2pzdGF0cyIsZGVwZW5kZW5jaWVzPVRSVUUpDQojZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJzdHJlbmdlamFja2UvZ2dlZmZlY3RzIixkZXBlbmRlbmNpZXM9VFJVRSkNCiNkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoInN0cmVuZ2VqYWNrZS9zalBsb3QiLGRlcGVuZGVuY2llcz1UUlVFKQ0KI2RldnRvb2xzOjppbnN0YWxsX2dpdGh1YigibG1lNC9sbWU0IixkZXBlbmRlbmNpZXM9VFJVRSkNCiNwYWNtYW46OnBfaW5zdGFsbF9naCgic3lzdGF0cy9iaW5vY3VsYVIiKQ0KDQpwYWNtYW46OnBfbG9hZCh0aWR5dmVyc2UsIGhhdmVuLCBtYWdyaXR0ciwgY2FyLCBwc3ljaCwgc2pQbG90LCBzanN0YXRzLCBzam1pc2MsIGxtZTQsIGJpbm9jdWxhUiwgTXVNSW4pDQoNCg0KYGBgDQoNCiMgTG9hZCBpbiBEYXRhDQoNCmBgYHtyfQ0KYXJhYjQgPC0gcmVhZF9zcHNzKCJkYXRhL2FyYWI0LnNhdiIpDQphcmFiMyA8LSByZWFkX3Nwc3MoImRhdGEvYXJhYjMuc2F2IikNCg0KIyBhcmFiNCA8LSBnZXQobG9hZCh1cmwoImh0dHBzOi8vZ2l0aHViLmNvbS9mYXZzdGF0cy9Hb2RseUdvdmVybmFuY2UvcmF3L21hc3Rlci9kYXRhL2FyYWI0LlJkYXRhIikpKQ0KDQoNCmBgYA0KDQojIEluc3BlY3QgRGF0YQ0KDQpgYGB7cn0NCiNiX3NlbGVjdCA8LSBiaW5vY3VsYVI6OmJpbm9jdWxhUihhcmFiNCkNCiNkcHV0KGJfc2VsZWN0JHZhcl9jb2RlcykNCg0KI2luZGV4IDwtIGMoImNvdW50cnkiLCJ3dCIgLCJzYW1wbGUiICwiYTEiLCAicTEiLCAicTIiLCAicTEzIiwgInE1MTgyIiwgDQojInE1MTg0IiwgInE2MDEzIiwgInE2MDE0IiwgInE2MDE4IiwgInE2MDExOCIsICJxNjA1YSIsICJxNjA2MSIsICJxNjA2MiIsIA0KIyJxNjA2MyIsICJxNjA2NCIsICJxNjA3MSIsICJxNjA3NCIsICJxNjA3NiIsICJxNzA3IiwgInE3MDgiLCANCiMicTcxMTQiLCAicTEwMDEiLCAicTEwMDIiLCAicTEwMDMiLCAidDEwMDMiLCAicTEwMDQiLCAicTEwMDUiLCANCiMicTYwOSIsICJxNjEwMSIsICJxNjEwNiIsICJxMTAxMiIsICJxMTAxMmEiLCAicTEwMTYiKQ0KIw0KI2FyYWI0ICU8PiUNCiMgIHNlbGVjdChpbmRleCkNCiMNCiNhcmFiNA0KI3ZpZXdfZGYyKGFyYWIzLCBoaWRlLnByb2dyZXNzID0gVCkNCiMgc2F2ZShhcmFiNCwgZmlsZSA9ICJkYXRhL2FyYWI0LlJkYXRhIikNCmBgYA0KDQojIEZpbHRlciBEYXRhDQoNCmBgYHtyfQ0KYXJhYjQgJTw+JQ0KICBmaWx0ZXIocTEwMTIgPT0gMSkgJT4lI29ubHkgTXVzbGltcw0KICBtdXRhdGUoc2FtcGxlID0gaWZlbHNlKGlzLm5hKHNhbXBsZSkgfCBzYW1wbGUgPT0gMSwgMSwgMikpICU+JSANCiAgZmlsdGVyKHNhbXBsZSAhPSAyKSAjb25seSBub24tcmVmdWdlZXMNCg0KYXJhYjMgJTw+JQ0KICBmaWx0ZXIocTEwMTIgPT0gMSkgI29ubHkgTXVzbGltcw0KDQphcmFiMw0KYXJhYjQNCg0KDQoNCmBgYA0KDQojIFJlY29kZSBEYXRhDQoNCiMjIEFyYWIzDQoNCmBgYHtyfQ0KDQphcmFiMyAlPD4lIA0KICBtdXRhdGUoY250cnkgPSBzam1pc2M6OnRvX2xhYmVsKGNvdW50cnkpKSAlPiUgDQogIG11dGF0ZShyZWdpb24gPSBzam1pc2M6OnRvX2xhYmVsKGExKSkgJT4lIA0KICBtdXRhdGUoZ292ZXJub3JhdGUgPSBzam1pc2M6OnRvX2xhYmVsKHExKSkgJT4lIA0KICBtdXRhdGUoeWVhciA9IGx1YnJpZGF0ZTo6eWVhcihkYXRlKSkNCg0KICAjIERlcGVuZGVudCBWYXJpYWJsZQ0KYXJhYjMgJTw+JSANCiAgbXV0YXRlKGlzbGFtaXN0cGFydGllczEgPSBpZmVsc2UocTUxOGEyID4gNSwgTkEsIDUgLSBxNTE4YTIpKSAlPiUNCiAgbXV0YXRlKGlzbGFtaXN0cGFydGllczIgPSBpZmVsc2UocTUxOGIyID4gNSwgTkEsIDUgLSBxNTE4YjIpKSAlPiUgDQogIG11dGF0ZShpc2xhbWlzdHBhcnRpZXMgPSBjYXNlX3doZW4oDQogICAgICAgIGlzbGFtaXN0cGFydGllczEgPT0gMSB+IDEsDQogICAgICAgIGlzbGFtaXN0cGFydGllczEgPT0gMiB+IDIsDQogICAgICAgIGlzbGFtaXN0cGFydGllczEgPT0gMyB+IDMsDQogICAgICAgIGlzbGFtaXN0cGFydGllczEgPT0gNCB+IDQsDQogICAgICAgIGlzbGFtaXN0cGFydGllczIgPT0gMSB+IDEsDQogICAgICAgIGlzbGFtaXN0cGFydGllczIgPT0gMiB+IDIsDQogICAgICAgIGlzbGFtaXN0cGFydGllczIgPT0gMyB+IDMsDQogICAgICAgIGlzbGFtaXN0cGFydGllczIgPT0gNCB+IDQpDQogICAgKSAlPiUgIA0KICBtdXRhdGUoaXNsYW1pc3Rnb3YgPSBpZmVsc2UocTUxODQgPiA1LCBOQSwgNSAtIHE1MTg0KSkgJT4lIA0KICBtdXRhdGUocmVsaWdpbnRlcmZlcmUgPSBpZmVsc2UocTYwNjEgPiA1LCBOQSwgcTYwNjEpKSAlPiUgDQogIG11dGF0ZShyZWxpZ2xlYWRlcnMgPSBpZmVsc2UocTYwNjIgPiA1LCBOQSwgNSAtIHE2MDYyKSkgJT4lIA0KICBtdXRhdGUocmVsaWdsZWFkZXJzaW5mbCA9IGlmZWxzZShxNjA2MyA+IDUsIE5BLCA1IC0gcTYwNjMpKSAlPiUNCiAgbXV0YXRlKHNlcGVyYXRpb24gPSBpZmVsc2UocTYwNjQgPiA1LCBOQSwgcTYwNjQpKSAlPiUgDQogIG11dGF0ZShyZWxpZ3BhcnR5ID0gUmVjb2RlKHE2MDVhLCAiMSA9IDE7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMiA9IDE7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMyA9IDA7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNCA9IDA7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNSA9IDA7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA4ID0gMDsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDkgPSBOQSIpKSAlPiUgDQogIG11dGF0ZShyZWxpZ3BhcnR5MiA9IFJlY29kZShxNjA1YSwgIjEgPSA1Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAyID0gNDsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMyA9IDI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDQgPSAxOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA1ID0gMzsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA4ID0gTkE7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOSA9IE5BIikpDQoNCmlmZWxzZTRjYXRfcmVjIDwtIGZ1bmN0aW9uKHZhcmlhYmxlKSB7DQogIHJlY29kZWQgPC0gaWZlbHNlKHZhcmlhYmxlID09IDAgfCB2YXJpYWJsZSA+IDUsIE5BLCA1IC0gdmFyaWFibGUpDQogIHJldHVybihyZWNvZGVkKQ0KfQ0KDQoNCmFyYWIzICU8PiUgDQogIG11dGF0ZShmZW1hbGUgPSBpZmVsc2Uoc2V4ID09IDIsIDEsIDApKSAlPiUgDQogIG11dGF0ZSh3b3JrID0gaWZlbHNlKHExMDA0ID09IDAgfCBxMTAwNCA+IDUsIE5BLCBhYnMocTEwMDQgLSAyKSkpICU+JSANCiAgbXV0YXRlKGluY29tZSA9IGlmZWxzZTRjYXRfcmVjKHExMDE2KSkgJT4lIA0KICBtdXRhdGUoYWdlID0gaWZlbHNlKHExMDAxID09IDAgfCBxMTAwMSA9PSA5OTk5LCBOQSwgcTEwMDEpKSAlPiUgDQogIG11dGF0ZShlZHVjID0gY2FzZV93aGVuKA0KICAgICAgICBxMTAwMyA9PSAwIH4gTkFfcmVhbF8sDQogICAgICAgIHExMDAzID09IDk5IH4gTkFfcmVhbF8sDQogICAgICAgIHExMDAzID09IDUgfiA0LA0KICAgICAgICBxMTAwMyA9PSA2IH4gNSwNCiAgICAgICAgcTEwMDMgPT0gNyB+IDYsDQogICAgICAgIHExMDAzeWVtID09IDAgfiBOQV9yZWFsXywNCiAgICAgICAgcTEwMDN5ZW0gPT0gOTkgfiBOQV9yZWFsXywNCiAgICAgICAgcTEwMDN5ZW0gPT0gNCB+IDMsDQogICAgICAgIHExMDAzeWVtID09IDUgfiA0LA0KICAgICAgICBxMTAwM3llbSA9PSA2IH4gNSwNCiAgICAgICAgcTEwMDN5ZW0gPT0gNyB+IDUsDQogICAgICAgIHExMDAzeWVtID09IDggfiA2LA0KICAgICAgICBxMTAwM3QgPT0gMCB+IE5BX3JlYWxfLA0KICAgICAgICBxMTAwM3QgPT0gOTkgfiBOQV9yZWFsXywNCiAgICAgICAgcTEwMDN0ID09IDEgfiAxLA0KICAgICAgICBxMTAwM3QgPT0gMiB+IDIsDQogICAgICAgIHExMDAzdCA9PSAzIH4gMywNCiAgICAgICAgcTEwMDN0ID09IDQgfiA0LA0KICAgICAgICBxMTAwM3QgPT0gNSB+IDUsDQogICAgICAgIHExMDAzdCA9PSA2IH4gNiwNCiAgICBUUlVFIH4gYXMubnVtZXJpYyhxMTAwMykpDQogICAgKSAlPiUgDQogIG11dGF0ZShpbmZfdXMgPSBpZmVsc2UocTcwMTEgPT0gMCB8IHE3MDExID4gNSwgTkEsIHE3MDExKSkgJT4lIA0KICBtdXRhdGUoaW5mX2V1ID0gaWZlbHNlKHE3MDEyID09IDAgfCBxNzAxMiA+IDUsIE5BLCBxNzAxMikpICU+JSANCiAgbXV0YXRlKGdsb2JhbGlzbSA9IGlmZWxzZShxNzAxYiA9PSAwIHwgcTcwMWIgPiA1LCBOQSwgcTcwMWIpKSAlPiUgDQogIG11dGF0ZShwcmF5ID0gaWZlbHNlKHE2MTAxID09IDAgfCBxNjEwMSA+IDUsIE5BLCA2IC0gcTYxMDEpKSAlPiUgDQogIG11dGF0ZShxdXJhbiA9IGlmZWxzZShxNjEwNiA9PSAwIHwgcTYxMDYgPiA1LCBOQSwgNiAtIHE2MTA2KSkgJT4lDQogIG11dGF0ZSh3b21hbndvcmsgPSBpZmVsc2UocTYwMTIgPT0gMCB8IHE2MDEyID4gNSwgTkEsIHE2MDEyKSkgJT4lIA0KICBtdXRhdGUod29tZW5sZWFkZXIgPSBpZmVsc2U0Y2F0X3JlYyhxNjAxMykpICU+JSANCiAgbXV0YXRlKHdvbWVuZWR1YyA9IGlmZWxzZTRjYXRfcmVjKHE2MDE0KSkgJT4lIA0KICBtdXRhdGUobm9kZW1vYyA9IGlmZWxzZShxNjA3MSA9PSAwIHwgcTYwNzEgPiA1LCBOQSwgcTYwNzEpKSAlPiUgDQogIG11dGF0ZShnZW5kZXJhcGFydHVuaSA9IGlmZWxzZTRjYXRfcmVjKHE2MDc0KSkgJT4lIA0KICBtdXRhdGUoY292ZXJ1cCA9IGlmZWxzZTRjYXRfcmVjKHE2MDc2KSkgJT4lIA0KICBzZWxlY3QoY250cnksIHllYXIsIHJlZ2lvbiwgZ292ZXJub3JhdGUsIGlzbGFtaXN0cGFydGllcyAsIGlzbGFtaXN0Z292LCByZWxpZ2ludGVyZmVyZSwgcmVsaWdsZWFkZXJzLCByZWxpZ2xlYWRlcnNpbmZsLCBzZXBlcmF0aW9uLCByZWxpZ3BhcnR5LCByZWxpZ3BhcnR5MiwgZmVtYWxlLCB3b3JrLCBpbmNvbWUsICBhZ2UsIGVkdWMsIGdsb2JhbGlzbSwgcHJheSwgcXVyYW4sIHdvbWFud29yaywgd29tZW5sZWFkZXIsIHdvbWVuZWR1Yywgbm9kZW1vYywgZ2VuZGVyYXBhcnR1bmksIGNvdmVydXAsIGluZl91cywgaW5mX2V1LCB3dCkNCg0KDQoNCg0KDQpgYGANCg0KIyMgQXJhYjQNCg0KYGBge3J9DQp0YWJsZShhcmFiNCRjb3VudHJ5KQ0KDQphcmFiNCAlPD4lIA0KICBtdXRhdGUoY250cnkgPSBzam1pc2M6OnRvX2xhYmVsKGNvdW50cnkpKSAlPiUgDQogIG11dGF0ZShyZWdpb24gPSBzam1pc2M6OnRvX2xhYmVsKGExKSkgJT4lIA0KICBtdXRhdGUoZ292ZXJub3JhdGUgPSBzam1pc2M6OnRvX2xhYmVsKHExKSkgJT4lIA0KICBtdXRhdGUoeWVhciA9IDIwMTYpIyU+JQ0KIyAgbXV0YXRlKGRpc3RyaWN0ID0gc2ptaXNjOjp0b19sYWJlbChxMikpIA0KDQojIERlcGVuZGVudCBWYXJpYWJsZQ0KYXJhYjQgJTw+JSANCiAgbXV0YXRlKGlzbGFtaXN0cGFydGllcyA9IGlmZWxzZShxNTE4MiA+IDUsIE5BLCA1IC0gcTUxODIpKSAlPiUgDQogIG11dGF0ZShpc2xhbWlzdGdvdiA9IGlmZWxzZShxNTE4NCA+IDUsIE5BLCA1IC0gcTUxODQpKSAlPiUgDQogIG11dGF0ZShyZWxpZ2ludGVyZmVyZSA9IGlmZWxzZShxNjA2MSA+IDUsIE5BLCBxNjA2MSkpICU+JSANCiAgbXV0YXRlKHJlbGlnbGVhZGVycyA9IGlmZWxzZShxNjA2MiA+IDUsIE5BLCA1IC0gcTYwNjIpKSAlPiUgDQogIG11dGF0ZShyZWxpZ2xlYWRlcnNpbmZsID0gaWZlbHNlKHE2MDYzID4gNSwgTkEsIDUgLSBxNjA2MykpICU+JQ0KICBtdXRhdGUoc2VwZXJhdGlvbiA9IGlmZWxzZShxNjA2NCA+IDUsIE5BLCBxNjA2NCkpICU+JSANCiAgbXV0YXRlKHJlbGlncGFydHkgPSBSZWNvZGUocTYwNWEsICIxID0gMTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAyID0gMTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAzID0gMDsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA0ID0gMDsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA1ID0gMDsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDk4ID0gMDsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDk5ID0gTkEiKSkgJT4lIA0KICBtdXRhdGUocmVsaWdwYXJ0eTIgPSBSZWNvZGUocTYwNWEsICIxID0gNTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMiA9IDQ7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDMgPSAyOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA0ID0gMTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNSA9IDM7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOTggPSBOQTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA5OSA9IE5BIikpDQoNCg0KDQphcmFiNCAlPD4lIA0KICBtdXRhdGUoZmVtYWxlID0gaWZlbHNlKHExMDAyID09IDIsIDEsIDApKSAlPiUgDQogIG11dGF0ZSh3b3JrID0gaWZlbHNlKHExMDA0ID09IDAgfCBxMTAwNCA+IDUsIE5BLCBhYnMocTEwMDQgLSAyKSkpICU+JSANCiAgbXV0YXRlKGluY29tZSA9IGlmZWxzZTRjYXRfcmVjKHExMDE2KSkgJT4lIA0KICBtdXRhdGUoYWdlID0gaWZlbHNlKHExMDAxID09IDAgfCBxMTAwMSA9PSA5OTk5LCBOQSwgcTEwMDEpKSAlPiUgDQogIG11dGF0ZShlZHVjID0gY2FzZV93aGVuKA0KICAgICAgICBxMTAwMyA9PSAwIH4gTkFfcmVhbF8sDQogICAgICAgIHExMDAzID09IDk4IH4gTkFfcmVhbF8sDQogICAgICAgIHExMDAzID09IDk5IH4gTkFfcmVhbF8sDQogICAgICAgIHExMDAzID09IDUgfiA0LA0KICAgICAgICBxMTAwMyA9PSA2IH4gNSwNCiAgICAgICAgcTEwMDMgPT0gNyB+IDYsDQogICAgICAgIHQxMDAzID09IDAgfiBOQV9yZWFsXywNCiAgICAgICAgdDEwMDMgPT0gOTggfiBOQV9yZWFsXywNCiAgICAgICAgdDEwMDMgPT0gOTkgfiBOQV9yZWFsXywNCiAgICAgICAgdDEwMDMgPT0gMyB+IDMsDQogICAgICAgIHQxMDAzID09IDQgfiA0LA0KICAgICAgICB0MTAwMyA9PSA1IH4gNSwNCiAgICAgICAgdDEwMDMgPT0gNiB+IDYsDQogICAgVFJVRSB+IGFzLm51bWVyaWMocTEwMDMpKQ0KICAgICkgJT4lIA0KICBtdXRhdGUoaW5mX3VzID0gaWZlbHNlKHE3MDExID09IDAgfCBxNzAxMSA+IDUsIE5BLCBxNzAxMSkpICU+JSANCiAgbXV0YXRlKGluZl9ldSA9IGlmZWxzZShxNzAxMiA9PSAwIHwgcTcwMTIgPiA1LCBOQSwgcTcwMTIpKSAlPiUgDQogIG11dGF0ZShnbG9iYWxpc20gPSBpZmVsc2UocTcwMWIgPT0gMCB8IHE3MDFiID4gNSwgTkEsIHE3MDFiKSkgJT4lIA0KICBtdXRhdGUocHJheSA9IGlmZWxzZShxNjEwMSA9PSAwIHwgcTYxMDEgPiA1LCBOQSwgNiAtIHE2MTAxKSkgJT4lIA0KICBtdXRhdGUocXVyYW4gPSBpZmVsc2UocTYxMDYgPT0gMCB8IHE2MTA2ID4gNSwgTkEsIDYgLSBxNjEwNikpICU+JSANCiAgbXV0YXRlKHdvbWFud29yayA9IGlmZWxzZShxNjAxMiA9PSAwIHwgcTYwMTIgPiA1LCBOQSwgcTYwMTIpKSAlPiUgDQogIG11dGF0ZSh3b21lbmxlYWRlciA9IGlmZWxzZTRjYXRfcmVjKHE2MDEzKSkgJT4lIA0KICBtdXRhdGUod29tZW5lZHVjID0gaWZlbHNlNGNhdF9yZWMocTYwMTQpKSAlPiUgDQogIG11dGF0ZShub2RlbW9jID0gaWZlbHNlKHE2MDcxID09IDAgfCBxNjA3MSA+IDUsIE5BLCBxNjA3MSkpICU+JSANCiAgbXV0YXRlKGdlbmRlcmFwYXJ0dW5pID0gaWZlbHNlNGNhdF9yZWMocTYwNzQpKSAlPiUgDQogIG11dGF0ZShjb3ZlcnVwID0gaWZlbHNlNGNhdF9yZWMocTYwNzYpKSAlPiUgDQogIHNlbGVjdChjbnRyeSwgeWVhciwgcmVnaW9uLCBnb3Zlcm5vcmF0ZSAsIGlzbGFtaXN0cGFydGllcyAsIGlzbGFtaXN0Z292LCByZWxpZ2ludGVyZmVyZSwgcmVsaWdsZWFkZXJzLCByZWxpZ2xlYWRlcnNpbmZsLCBzZXBlcmF0aW9uLCByZWxpZ3BhcnR5LCByZWxpZ3BhcnR5MiwgZmVtYWxlLCB3b3JrLCBpbmNvbWUsICBhZ2UsIGVkdWMsIGdsb2JhbGlzbSwgcHJheSwgcXVyYW4sIHdvbWFud29yaywgd29tZW5sZWFkZXIsIHdvbWVuZWR1Yywgbm9kZW1vYywgZ2VuZGVyYXBhcnR1bmksIGNvdmVydXAsIGluZl91cywgaW5mX2V1LCB3dCkNCg0KYGBgDQoNCg0KIyBNZXJnaW5nDQoNCmBgYHtyfQ0KYXJhYjM7YXJhYjQNCg0KYXJhYiA8LSByYmluZChhcmFiNCxhcmFiMykNCg0KYXJhYg0KDQp0YWJsZShhcmFiJHllYXIpDQp0YWJsZShhcmFiJGNudHJ5KQ0KYGBgDQoNCiMgRmFjdG9yIEFuYWx5c2lzDQoNCmBgYHtyfQ0KIyBmMSA8LSBhcmFiICU+JSANCiMgICBzZWxlY3QoaXNsYW1pc3RwYXJ0aWVzLCBpc2xhbWlzdGdvdiwgDQojICAgICAgICAgIHJlbGlnbGVhZGVycywgcmVsaWdsZWFkZXJzaW5mbCkgJT4lDQojICAgIyBuYS5vbWl0KCkgJT4lIA0KIyAgIHBzeWNoOjpmYSgxLCByb3RhdGUgPSAidmFyaW1heCIsICAgDQojICAgICAgICAgZm0gPSAicGEiLA0KIyAgICAgICAgIHNjb3JlcyA9ICJyZWdyZXNzaW9uIiwNCiMgICAgICAgICB3ZWlnaHQgPSBuYS5vbWl0KGFyYWIkd3QpICApICAgICAgICAgDQojIGZhLmRpYWdyYW0oZjEpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KIyBmMSAgICAgICAgICAgICAgDQoNCmYyIDwtIGFyYWIgJT4lIA0KICBzZWxlY3QoaXNsYW1pc3RwYXJ0aWVzLCBpc2xhbWlzdGdvdiwgDQogICAgICAgICByZWxpZ2xlYWRlcnMsIHJlbGlnbGVhZGVyc2luZmwpICU+JSANCiAgcHN5Y2g6OnBjYSh3ZWlnaHQgPSBhcmFiJHd0KSANCg0KYXJhYiAlPiUgDQogIHNlbGVjdChpc2xhbWlzdHBhcnRpZXMsIGlzbGFtaXN0Z292LCANCiAgICAgICAgIHJlbGlnbGVhZGVycywgcmVsaWdsZWFkZXJzaW5mbCkgJT4lIA0KICBhbHBoYSgpIA0KDQphcmFiICU+JSANCiAgc2VsZWN0KGlzbGFtaXN0cGFydGllcywgaXNsYW1pc3Rnb3YsIA0KICAgICAgICAgcmVsaWdsZWFkZXJzLCByZWxpZ2xlYWRlcnNpbmZsKSAlPiUgDQogIEtNTygpIA0KDQoNCmFyYWI0ICU+JSANCiAgc2VsZWN0KGlzbGFtaXN0cGFydGllcywgaXNsYW1pc3Rnb3YsIA0KICAgICAgICAgcmVsaWdsZWFkZXJzLCByZWxpZ2xlYWRlcnNpbmZsLA0KICAgICAgICAgcmVsaWdwYXJ0eTIsIHNlcGVyYXRpb24sDQogICAgICAgICByZWxpZ2ludGVyZmVyZSkgJT4lIA0KICBuYS5vbWl0KCkgJT4lIA0KICBjb3IoKSAgDQoNCiMgYXJhYiA8LSBwcmVkaWN0LnBzeWNoKGYxLCBhcmFiICU+JSANCiMgICBzZWxlY3QoaXNsYW1pc3RwYXJ0aWVzLCBpc2xhbWlzdGdvdiwgDQojICAgICAgICAgIHJlbGlnbGVhZGVycywgcmVsaWdsZWFkZXJzaW5mbCkpICU+JSANCiMgICB0YmxfZGYoKSAlPiUgDQojICAgY2JpbmQoYXJhYikgJT4lIA0KIyAgIG11dGF0ZShpc2xhbWlzbV9mYSA9IFBBMSkNCg0KYXJhYiA8LSBwcmVkaWN0LnBzeWNoKGYyLCBhcmFiICU+JSANCiAgc2VsZWN0KGlzbGFtaXN0cGFydGllcywgaXNsYW1pc3Rnb3YsIA0KICAgICAgICAgcmVsaWdsZWFkZXJzLCByZWxpZ2xlYWRlcnNpbmZsKSkgJT4lIA0KICB0YmxfZGYoKSAlPiUgDQogIHRyYW5zbXV0ZShpc2xhbWlzbSA9IFBDMSkgJT4lIA0KICBjYmluZChhcmFiKSANCg0KIyU+JSANCiMgIGdncGxvdChhZXMoaXNsYW1pc20pKSArDQojICBnZW9tX2hpc3RvZ3JhbSgpICsNCiMgIGZhY2V0X3dyYXAofmNudHJ5LCBzY2FsZXMgPSAiZnJlZSIpDQoNCiNzalBsb3Q6OnZpZXdfZGYoYXJhYiwgc2hvdy5mcnEgPSBULCBzaG93LnByYyA9IFQpDQojIA0KIyBjb3IudGVzdChhcmFiJFBDMSwgYXJhYiRQQTEpDQoNCmBgYA0KDQojIENyZWF0aW5nIGluZGljZXMNCg0KYGBge3J9DQpmMSA8LSBhcmFiICU+JSANCiAgc2VsZWN0KHdvbWFud29yaywgd29tZW5sZWFkZXIsIHdvbWVuZWR1YykgJT4lIA0KICBmYSgxLCByb3RhdGUgPSAicHJvbWF4IiwgICANCiAgICAgICAgZm0gPSAicGEiLA0KICAgICAgICBzY29yZXMgPSAicmVncmVzc2lvbiIpICAgICAgICAgICANCmZhLmRpYWdyYW0oZjEpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KZjEgICAgICAgIA0KDQphcmFiICU+JSANCiAgc2VsZWN0KHdvbWFud29yaywgd29tZW5sZWFkZXIsIHdvbWVuZWR1YykgJT4lIA0KICBwc3ljaDo6cGNhKCkgDQoNCmYyIDwtIGFyYWIgJT4lIA0KICBzZWxlY3QocHJheSwgcXVyYW4pICU+JSANCiAgZmEoMSwgcm90YXRlID0gInByb21heCIsICAgDQogICAgICAgIGZtID0gInBhIiwNCiAgICAgICAgc2NvcmVzID0gInJlZ3Jlc3Npb24iKSAgICAgICAgICAgDQpmYS5kaWFncmFtKGYyKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCmYyICAgIA0KDQpmMyA8LSBhcmFiICU+JSANCiAgc2VsZWN0KG5vZGVtb2MsIGdlbmRlcmFwYXJ0dW5pLCBjb3ZlcnVwKSAlPiUgDQogIGZhKDEsIHJvdGF0ZSA9ICJwcm9tYXgiLCAgIA0KICAgICAgICBmbSA9ICJwYSIsDQogICAgICAgIHNjb3JlcyA9ICJyZWdyZXNzaW9uIikgICAgICAgICAgIA0KZmEuZGlhZ3JhbShmMykgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQpmMyAgICANCg0KYXJhYiAlPiUgDQogIHNlbGVjdChub2RlbW9jLCBnZW5kZXJhcGFydHVuaSwgY292ZXJ1cCkgJT4lIA0KICBLTU8oKQ0KDQphcmFiICU+JSANCiAgc2VsZWN0KG5vZGVtb2MsIGdlbmRlcmFwYXJ0dW5pLCBjb3ZlcnVwKSAlPiUgDQogIHBzeWNoOjpwY2EoKQ0KDQphcmFiICU+JSANCiAgc2VsZWN0KGluZl9ldSwgaW5mX3VzKSAlPiUgDQogIHBzeWNoOjpwY2EoKQ0KDQoNCnJhbmdlMDEgPC0gZnVuY3Rpb24oeCl7KHggLSBtaW4oeCwgbmEucm0gPSBUKSkgLyAobWF4KHgsIG5hLnJtID0gVCkgLSBtaW4oeCwgbmEucm0gPSBUKSl9DQoNCg0KYXJhYl9yZWcgPC0gYXJhYiAlPiUgDQogIG11dGF0ZShwYXRyaWFyY2hhbHZhbHVlcyA9IHJhbmdlMDEod29tYW53b3JrICsgd29tZW5sZWFkZXIgKyB3b21lbmVkdWMpKSAgJT4lIA0KICBtdXRhdGUocGVyc29uYWxwaWV0eSA9IHJhbmdlMDEocHJheSArIHF1cmFuKSkgJT4lIA0KICBtdXRhdGUoYW50aXdlc3Rlcm4gPSByYW5nZTAxKGluZl9ldSArIGluZl91cykpICU+JSANCiAgbXV0YXRlKGlzbGFtaXNtID0gcmFuZ2UwMShpc2xhbWlzbSkgKiAxMDApICU+JSANCiAgbXV0YXRlX2F0KHZhcnMoaXNsYW1pc3RwYXJ0aWVzOmluZl9ldSksIHJhbmdlMDEpICU+JSANCiMgIG11dGF0ZShpc2xhbWlzbSA9IHNjYWxlKGlzbGFtaXNtKSkgJT4lIA0KIyAgbXV0YXRlKGlzbGFtaXNtID0gc2NhbGUoaXNsYW1pc20pKSAlPiUgDQojICBtdXRhdGVfaWYoLnByZWRpY2F0ZSA9IGlzLmRvdWJsZSwgc2NhbGUpIA0KICBtdXRhdGUobGliZXJhbGlzbGFtID0gcmFuZ2UwMShub2RlbW9jICsgZ2VuZGVyYXBhcnR1bmkgKyBjb3ZlcnVwKSkgJT4lIA0KICBtdXRhdGUoY250cnllYXJzID0gcGFzdGUoY250cnksIHllYXIpKSAlPiUgDQogIG11dGF0ZSh5ZWFyXzIwMTYgPSBpZmVsc2UoeWVhciA9PSAyMDE2LCAxLCAwKSkgJT4lIA0KICBtdXRhdGUoeWVhcl8yMDE0ID0gaWZlbHNlKHllYXIgPT0gMjAxNCwgMSwgMCkpICU+JSANCiAgbXV0YXRlKHllYXJfMjAxMyA9IGlmZWxzZSh5ZWFyID09IDIwMTMsIDEsIDApKSAlPiUgDQogIG11dGF0ZSh5ZWFyXzIwMTIgPSBpZmVsc2UoeWVhciA9PSAyMDEyLCAxLCAwKSkgDQoNCiMgYXJhYl9yZWckaXNsYW1pc21fZmEgPC0gYXMubnVtZXJpYyhyYW5nZTAxKGFyYWJfcmVnJGlzbGFtaXNtX2ZhKSAqIDEwMCkNCiMgYXJhYl9yZWckaXNsYW1pc21fcGNhIDwtIGFzLm51bWVyaWMocmFuZ2UwMShhcmFiX3JlZyRpc2xhbWlzbV9wY2EpICogMTAwKQ0KIyANCiMgYXJhYl9yZWckaW5jb21lICAgICAgICAgICAgIDwtIGFzLm51bWVyaWMoc2NhbGUoYXJhYl9yZWckaW5jb21lKSkNCiMgYXJhYl9yZWckYWdlICAgICAgICAgICAgICAgIDwtIGFzLm51bWVyaWMoc2NhbGUoYXJhYl9yZWckYWdlKSkNCiMgYXJhYl9yZWckZWR1YyAgICAgICAgICAgICAgIDwtIGFzLm51bWVyaWMoc2NhbGUoYXJhYl9yZWckZWR1YykpIA0KIyBhcmFiX3JlZyRnbG9iYWxpc20gICAgICAgICAgPC0gYXMubnVtZXJpYyhzY2FsZShhcmFiX3JlZyRnbG9iYWxpc20pKSAgIA0KIyBhcmFiX3JlZyRwZXJzb25hbHBpZXR5ICAgICAgPC0gYXMubnVtZXJpYyhzY2FsZShhcmFiX3JlZyRwZXJzb25hbHBpZXR5KSkgICAgICAgDQojIGFyYWJfcmVnJHBhdHJpYXJjaGFsdmFsdWVzICA8LSBhcy5udW1lcmljKHNjYWxlKGFyYWJfcmVnJHBhdHJpYXJjaGFsdmFsdWVzKSkgICAgICAgICAgIA0KIyBhcmFiX3JlZyRsaWJlcmFsaXNsYW0gICAgICAgPC0gYXMubnVtZXJpYyhzY2FsZShhcmFiX3JlZyRsaWJlcmFsaXNsYW0pKSAgICAgDQojIA0KIyBoaXN0KGFyYWJfcmVnJGxpYmVyYWxpc2xhbSkNCiMgDQojIA0KIyBhcmFiX3JlZyAlPiUgDQojICAgc2VsZWN0KGlzbGFtaXNtX3BjYSAsIGZlbWFsZSAsIHdvcmsgLCBpbmNvbWUgLCBhZ2UgLCBlZHVjICwgZ2xvYmFsaXNtICwgcGVyc29uYWxwaWV0eSAsIHBhdHJpYXJjaGFsdmFsdWVzICwgbGliZXJhbGlzbGFtLCBjbnRyeSkgJT4lIA0KIyAgIGRlc2NyKCkNCiMgICBuYS5vbWl0KCkgJT4lIA0KIyAgIHNlbGVjdChjbnRyeSkgJT4lIA0KIyAgIHRhYmxlKCkNCg0KdGFibGUoYXJhYiR5ZWFyLCBhcmFiJGNudHJ5KQ0KDQpzYXZlKGFyYWJfcmVnLCBmaWxlID0gImRhdGEvYXJhYl9yZWcuUmRhdGEiKQ0KYGBgDQoNCg0KIyBSZWdyZXNzaW9uDQoNCmBgYHtyfQ0KbW9kZWwwIDwtIGFyYWJfcmVnICU+JSANCiAgbG1lNDo6bG1lcihpc2xhbWlzbSB+IDEgKyAoMXxjbnRyeSksIGRhdGEgPSAuKQ0KDQppY2MobW9kZWwwKQ0KDQptb2RlbDFhIDwtIGxtZTQ6OmxtZXIoaXNsYW1pc21fcGNhIH4gZmVtYWxlICsgd29yayArIGluY29tZSArIGFnZSArIGVkdWMgKyBnbG9iYWxpc20gKyBwZXJzb25hbHBpZXR5ICsgcGF0cmlhcmNoYWx2YWx1ZXMgKyBub2RlbW9jICsgZ2VuZGVyYXBhcnR1bmkgKyBjb3ZlcnVwICsgKDF8Y250cnkpLCBkYXRhID0gYXJhYl9yZWcpDQoNCm1vZGVsMSA8LSBsbWU0OjpsbWVyKGlzbGFtaXNtIH4gZmVtYWxlICsgd29yayArIGluY29tZSArIGFnZSArIGVkdWMgKyBnbG9iYWxpc20gKyBhbnRpd2VzdGVybiArIHBlcnNvbmFscGlldHkgKyBwYXRyaWFyY2hhbHZhbHVlcyArIGxpYmVyYWxpc2xhbSArIHllYXJfMjAxMiArIHllYXJfMjAxMyArIHllYXJfMjAxNCArICgxfGNudHJ5KSwgZGF0YSA9IGFyYWJfcmVnLCB3ZWlnaHRzID0gd3QpDQoNCnRleHJlZzo6c2NyZWVucmVnKG1vZGVsMSkNCg0KYW5vdmEobW9kZWwxYSwgbW9kZWwxYikNCg0Kci5zcXVhcmVkR0xNTShtb2RlbDFhKQ0KDQpwbG90X21vZGVsKG1vZGVsMSwgdHlwZSA9ICJyZSIsIHNvcnQuZXN0ID0gVCwgc2hvdy52YWx1ZXMgPSBULCBzaG93LnAgPSBULCB2YWx1ZS5vZmZzZXQgPSAwLjUpDQoNCiNwbG90X21vZGVsKG1vZGVsMSwgdHlwZSA9ICJzdGQiLCBzb3J0LmVzdCA9IFQsIHNob3cudmFsdWVzID0gVCwgc2hvdy5wID0gVCwgdmFsdWUub2Zmc2V0ID0gMC41KQ0KDQpzanAubG1lcihtb2RlbDEsIHR5cGUgPSAiZmUuc3RkIiwgc29ydC5lc3QgPSBULCBzaG93LnZhbHVlcyA9IFQsIHNob3cucCA9IFQsIHkub2Zmc2V0ID0gMC40LCBwLmtyID0gRkFMU0UpDQoNCnBsb3RfbW9kZWwobW9kZWwxLCB0ZXJtcyA9IGMoInBlcnNvbmFscGlldHkiKSwgdHlwZSA9ICJlZmYiKQ0KDQppY2MobW9kZWwxKQ0KDQptb2RlbDIgPC0gbG1lNDo6bG1lcihpc2xhbWlzbV9wY2EgfiBmZW1hbGUgKyB3b3JrICsgaW5jb21lICsgYWdlICsgZWR1YyArIGdsb2JhbGlzbSArIHBlcnNvbmFscGlldHkgKyBwYXRyaWFyY2hhbHZhbHVlcyArIGxpYmVyYWxpc2xhbSArIGxpYmVyYWxpc2xhbSpwZXJzb25hbHBpZXR5ICsgKDF8Y250cnkveWVhciksIGRhdGEgPSBhcmFiX3JlZykNCg0KdGV4cmVnOjpzY3JlZW5yZWcobW9kZWwyKQ0KDQoNCnBsb3RfbW9kZWwobW9kZWwyLCBzb3J0LmVzdCA9IFQsIHNob3cudmFsdWVzID0gVCwgc2hvdy5wID0gVCwgdmFsdWUub2Zmc2V0ID0gMC41KQ0KDQpzanAuaW50KG1vZGVsMiwgcC5rciA9IEZBTFNFLCBtZHJ0LnZhbHVlcyA9ICJhbGwiKQ0KDQpzanAubG1lcihtb2RlbDIsIHR5cGUgPSAiZmUuc3RkIiwgc29ydC5lc3QgPSBULCBzaG93LnZhbHVlcyA9IFQsIHNob3cucCA9IFQsIHkub2Zmc2V0ID0gMC40LCBwLmtyID0gRkFMU0UpDQoNCg0KI3Bsb3RfbW9kZWwobW9kZWwyLCB0eXBlID0gImludCIpDQoNCnZpZi5tZXIgPC0gZnVuY3Rpb24gKGZpdCkgew0KICAjIyBhZGFwdGVkIGZyb20gcm1zOjp2aWYNCiAgDQogIHYgPC0gdmNvdihmaXQpDQogIG5hbSA8LSBuYW1lcyhmaXhlZihmaXQpKQ0KICANCiAgIyMgZXhjbHVkZSBpbnRlcmNlcHRzDQogIG5zIDwtIHN1bSgxICogKG5hbSA9PSAiSW50ZXJjZXB0IiB8IG5hbSA9PSAiKEludGVyY2VwdCkiKSkNCiAgaWYgKG5zID4gMCkgew0KICAgIHYgPC0gdlstKDE6bnMpLCAtKDE6bnMpLCBkcm9wID0gRkFMU0VdDQogICAgbmFtIDwtIG5hbVstKDE6bnMpXQ0KICB9DQogIA0KICBkIDwtIGRpYWcodileMC41DQogIHYgPC0gZGlhZyhzb2x2ZSh2LyhkICVvJSBkKSkpDQogIG5hbWVzKHYpIDwtIG5hbQ0KICB2DQp9DQoNCnZpZi5tZXIobW9kZWwyKQ0KDQoNCg0KbW9kZWwzIDwtIGxtZTQ6OmxtZXIoaXNsYW1pc21fcGNhIH4gZmVtYWxlICsgd29yayArIGluY29tZSArIGFnZSArIGVkdWMgKyBnbG9iYWxpc20gKyBwZXJzb25hbHBpZXR5ICsgcGF0cmlhcmNoYWx2YWx1ZXMgKyBub2RlbW9jICsgZ2VuZGVyYXBhcnR1bmkgKyBjb3ZlcnVwICsgcGF0cmlhcmNoYWx2YWx1ZXMqcGVyc29uYWxwaWV0eSArICgxfGNudHJ5L3llYXIpLCBkYXRhID0gYXJhYl9yZWcpDQoNCnRleHJlZzo6c2NyZWVucmVnKG1vZGVsMykNCg0KDQpwbG90X21vZGVsKG1vZGVsMywgc29ydC5lc3QgPSBULCBzaG93LnZhbHVlcyA9IFQsIHNob3cucCA9IFQsIHZhbHVlLm9mZnNldCA9IDAuNSkNCg0Kc2pwLmludChtb2RlbDMsIHAua3IgPSBGQUxTRSwgbWRydC52YWx1ZXMgPSAiYWxsIikNCg0Kc2pwLmxtZXIobW9kZWwzLCB0eXBlID0gImZlLnN0ZCIsIHNvcnQuZXN0ID0gVCwgc2hvdy52YWx1ZXMgPSBULCBzaG93LnAgPSBULCB5Lm9mZnNldCA9IDAuNCwgcC5rciA9IEZBTFNFKQ0KDQpgYGANCg0KDQpgYGB7cn0NCm1vZGVsMSA8LSBhcmFiX3JlZyAlPiUgDQogIGxtZTQ6OmxtZXIoaXNsYW1pc20gfiBmZW1hbGUgKyB3b3JrICsgaW5jb21lICsgYWdlICsgZWR1YyArIGdsb2JhbGlzbSArIHByYXkgKyBxdXJhbiArIHdvbWFud29yayArIHdvbWVubGVhZGVyICsgd29tZW5lZHVjICsgbm9kZW1vYyArIGdlbmRlcmFwYXJ0dW5pICsgY292ZXJ1cCArICgxfGNudHJ5L3llYXIpLCBkYXRhID0gLikNCg0KdGV4cmVnOjpzY3JlZW5yZWcobW9kZWwxKQ0KDQpwbG90X21vZGVsKG1vZGVsMSwgc29ydC5lc3QgPSBULCBzaG93LnZhbHVlcyA9IFQsIHNob3cucCA9IFQsIHZhbHVlLm9mZnNldCA9IDAuNSkNCg0KDQpwbG90X21vZGVsKG1vZGVsMSwgdGVybXMgPSBjKCJub2RlbW9jIiwgImZlbWFsZSIpLCB0eXBlID0gInByZWQiKQ0KDQptb2RlbDIgPC0gYXJhYl9yZWcgJT4lIA0KICBsbWU0OjpsbWVyKGlzbGFtaXNtIH4gZmVtYWxlICsgd29yayArIGluY29tZSArIGFnZSArIGVkdWMgKyBnbG9iYWxpc20gKyBwcmF5ICsgcXVyYW4gKyB3b21hbndvcmsgKyB3b21lbmxlYWRlciArIHdvbWVuZWR1YyArIG5vZGVtb2MgKyBnZW5kZXJhcGFydHVuaSArIGNvdmVydXAgKyBub2RlbW9jKnF1cmFuICsgKDF8Y250cnkveWVhciksIGRhdGEgPSAuKQ0KDQp0ZXhyZWc6OnNjcmVlbnJlZyhtb2RlbDIpDQpgYGANCg0KDQpgYGB7cn0NCnZpZXdfZGYyIDwtIGZ1bmN0aW9uICh4LCB3ZWlnaHQuYnkgPSBOVUxMLCBhbHRyLnJvdy5jb2wgPSBUUlVFLCBzaG93LmlkID0gVFJVRSwgDQogIHNob3cudHlwZSA9IEZBTFNFLCBzaG93LnZhbHVlcyA9IFRSVUUsIHNob3cuc3RyaW5nLnZhbHVlcyA9IEZBTFNFLCANCiAgc2hvdy5sYWJlbHMgPSBUUlVFLCBzaG93LmZycSA9IEZBTFNFLCBzaG93LnByYyA9IEZBTFNFLCANCiAgc2hvdy53dGQuZnJxID0gRkFMU0UsIHNob3cud3RkLnByYyA9IEZBTFNFLCBzaG93Lm5hID0gRkFMU0UsIA0KICBtYXgubGVuID0gMTUsIHNvcnQuYnkubmFtZSA9IEZBTFNFLCB3cmFwLmxhYmVscyA9IDUwLCBoaWRlLnByb2dyZXNzID0gRkFMU0UsIA0KICBDU1MgPSBOVUxMLCBlbmNvZGluZyA9IE5VTEwsIGZpbGUgPSBOVUxMLCB1c2Uudmlld2VyID0gVFJVRSwgDQogIG5vLm91dHB1dCA9IEZBTFNFLCByZW1vdmUuc3BhY2VzID0gVFJVRSkgDQp7DQogIGdldC5lbmNvZGluZyA8LSBmdW5jdGlvbihlbmNvZGluZywgZGF0YSA9IE5VTEwpIHsNCiAgaWYgKGlzLm51bGwoZW5jb2RpbmcpKSB7DQogICAgaWYgKCFpcy5udWxsKGRhdGEpICYmIGlzLmRhdGEuZnJhbWUoZGF0YSkpIHsNCiAgICAgICMgZ2V0IHZhcmlhYmxlIGxhYmVsDQogICAgICBsYWJzIDwtIHNqbGFiZWxsZWQ6OmdldF9sYWJlbChkYXRhW1sxXV0pDQogICAgICAjIGNoZWNrIGlmIHZlY3RvcnMgb2YgZGF0YSBmcmFtZSBoYXZlDQogICAgICAjIGFueSB2YWxpZCBsYWJlbC4gZWxzZSwgZGVmYXVsdCB0byB1dGYtOA0KICAgICAgaWYgKCFpcy5udWxsKGxhYnMpICYmIGlzLmNoYXJhY3RlcihsYWJzKSkNCiAgICAgICAgZW5jb2RpbmcgPC0gRW5jb2Rpbmcoc2psYWJlbGxlZDo6Z2V0X2xhYmVsKGRhdGFbWzFdXSkpDQogICAgICBlbHNlDQogICAgICAgIGVuY29kaW5nIDwtICJVVEYtOCINCiAgICAgICMgdW5rbm93biBlbmNvZGluZz8gZGVmYXVsdCB0byB1dGYtOA0KICAgICAgaWYgKGVuY29kaW5nID09ICJ1bmtub3duIikgZW5jb2RpbmcgPC0gIlVURi04Ig0KICAgIH0gZWxzZSBpZiAoLlBsYXRmb3JtJE9TLnR5cGUgPT0gInVuaXgiKQ0KICAgICAgZW5jb2RpbmcgPC0gIlVURi04Ig0KICAgIGVsc2UNCiAgICAgIGVuY29kaW5nIDwtICJXaW5kb3dzLTEyNTIiDQogIH0NCiAgcmV0dXJuKGVuY29kaW5nKQ0KfQ0KDQogIGhhc192YWx1ZV9sYWJlbHMgPC0gZnVuY3Rpb24oeCkgew0KICAhKGlzLm51bGwoYXR0cih4LCAibGFiZWxzIiwgZXhhY3QgPSBUKSkgJiYgaXMubnVsbChhdHRyKHgsICJ2YWx1ZS5sYWJlbHMiLCBleGFjdCA9IFQpKSkNCn0NCg0KICBzanUucm1zcGMgPC0gZnVuY3Rpb24oaHRtbC50YWJsZSkgew0KICBjbGVhbmVkIDwtIGdzdWIoIiAgICAgIDwiLCAiPCIsIGh0bWwudGFibGUsIGZpeGVkID0gVFJVRSwgdXNlQnl0ZXMgPSBUUlVFKQ0KICBjbGVhbmVkIDwtIGdzdWIoIiAgICA8IiwgIjwiLCBjbGVhbmVkLCBmaXhlZCA9IFRSVUUsIHVzZUJ5dGVzID0gVFJVRSkNCiAgY2xlYW5lZCA8LSBnc3ViKCIgIDwiLCAiPCIsIGNsZWFuZWQsIGZpeGVkID0gVFJVRSwgdXNlQnl0ZXMgPSBUUlVFKQ0KICByZXR1cm4oY2xlYW5lZCkNCiAgfQ0KICANCiAgZnJxLnZhbHVlIDwtIGZ1bmN0aW9uKGluZGV4LCB4LCBkZi52YWwsIHdlaWdodHMgPSBOVUxMKSB7DQogIHZhbHN0cmluZyA8LSAiIg0KICAjIGNoZWNrIGlmIHdlIGhhdmUgYSB2YWxpZCBpbmRleA0KICBpZiAoaW5kZXggPD0gbmNvbCh4KSAmJiAhaXMubnVsbChkZi52YWxbW2luZGV4XV0pKSB7DQogICAgIyBkbyB3ZSBoYXZlIHdlaWdodHM/DQogICAgaWYgKCFpcy5udWxsKHdlaWdodHMpKQ0KICAgICAgdmFyaWFiIDwtIHNqc3RhdHM6OndlaWdodCh4W1tpbmRleF1dLCB3ZWlnaHRzKQ0KICAgIGVsc2UNCiAgICAgIHZhcmlhYiA8LSB4W1tpbmRleF1dDQogICAgIyBjcmVhdGUgZnJlcXVlbmN5IHRhYmxlLiBzYW1lIGZ1bmN0aW9uIGFzIGZvcg0KICAgICMgc2p0LmZycSBhbmQgc2pwLmZycQ0KICAgIGZ0YWIgPC0gY3JlYXRlLmZycS5kZih2YXJpYWIsIDIwKSRteWRhdCRmcnENCiAgICAjIHJlbW92ZSBsYXN0IHZhbHVlLCB3aGljaCBpcyBOIGZvciBOQQ0KICAgIGlmIChsZW5ndGgoZnRhYikgPT0gMSAmJiBpcy5uYShmdGFiKSkgew0KICAgICAgdmFsc3RyaW5nIDwtICI8TkE+Ig0KICAgIH0gZWxzZSB7DQogICAgICBmb3IgKGkgaW4gMToobGVuZ3RoKGZ0YWIpIC0gMSkpIHsNCiAgICAgICAgdmFsc3RyaW5nIDwtIHBhc3RlMCh2YWxzdHJpbmcsIGZ0YWJbaV0pDQogICAgICAgIGlmIChpIDwgbGVuZ3RoKGZ0YWIpKSB2YWxzdHJpbmcgPC0gcGFzdGUwKHZhbHN0cmluZywgIjxicj4iKQ0KICAgICAgfQ0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICB2YWxzdHJpbmcgPC0gIiINCiAgfQ0KICByZXR1cm4odmFsc3RyaW5nKQ0KfQ0KDQpwcmMudmFsdWUgPC0gZnVuY3Rpb24oaW5kZXgsIHgsIGRmLnZhbCwgd2VpZ2h0cyA9IE5VTEwpIHsNCiAgdmFsc3RyaW5nIDwtICIiDQogICMgY2hlY2sgZm9yIHZhbGlkIGluZGljZXMNCiAgaWYgKGluZGV4IDw9IG5jb2woeCkgJiYgIWlzLm51bGwoZGYudmFsW1tpbmRleF1dKSkgew0KICAgICMgZG8gd2UgaGF2ZSB3ZWlnaHRzPw0KICAgIGlmICghaXMubnVsbCh3ZWlnaHRzKSkNCiAgICAgIHZhcmlhYiA8LSBzanN0YXRzOjp3ZWlnaHQoeFtbaW5kZXhdXSwgd2VpZ2h0cykNCiAgICBlbHNlDQogICAgICB2YXJpYWIgPC0geFtbaW5kZXhdXQ0KICAgICMgY3JlYXRlIGZyZXF1ZW5jeSB0YWJsZSwgYnV0IG9ubHkgZ2V0IHZhbGlkIHBlcmNlbnRhZ2VzDQogICAgZnRhYiA8LSBjcmVhdGUuZnJxLmRmKHZhcmlhYiwgMjApJG15ZGF0JHZhbGlkLnByYw0KICAgICMgcmVtb3ZlIGxhc3QgdmFsdWUsIHdoaWNoIGlzIGEgTkEgZHVtbXkNCiAgICBpZiAobGVuZ3RoKGZ0YWIpID09IDEgJiYgaXMubmEoZnRhYikpIHsNCiAgICAgIHZhbHN0cmluZyA8LSAiPE5BPiINCiAgICB9IGVsc2Ugew0KICAgICAgZm9yIChpIGluIDE6KGxlbmd0aChmdGFiKSAtIDEpKSB7DQogICAgICAgIHZhbHN0cmluZyA8LSBwYXN0ZTAodmFsc3RyaW5nLCBzcHJpbnRmKCIlLjJmIiwgZnRhYltpXSkpDQogICAgICAgIGlmIChpIDwgbGVuZ3RoKGZ0YWIpKSB2YWxzdHJpbmcgPC0gcGFzdGUwKHZhbHN0cmluZywgIjxicj4iKQ0KICAgICAgfQ0KICAgIH0NCiAgfSBlbHNlIHsNCiAgICB2YWxzdHJpbmcgPC0gIiINCiAgfQ0KICByZXR1cm4odmFsc3RyaW5nKQ0KfQ0KICANCiAgZW5jb2RpbmcgPC0gZ2V0LmVuY29kaW5nKGVuY29kaW5nLCB4KQ0KICBpZiAoIWlzLmRhdGEuZnJhbWUoeCkpIA0KICAgIHN0b3AoIlBhcmFtZXRlciBuZWVkcyB0byBiZSBhIGRhdGEgZnJhbWUhIiwgY2FsbC4gPSBGQUxTRSkNCiAgZGYudmFyIDwtIHNqbGFiZWxsZWQ6OmdldF9sYWJlbCh4KQ0KICBkZi52YWwgPC0gc2psYWJlbGxlZDo6Z2V0X2xhYmVscyh4KQ0KICBjb2xjbnQgPC0gbmNvbCh4KQ0KICBpZCA8LSBzZXFfbGVuKGNvbGNudCkNCiAgaWYgKHNvcnQuYnkubmFtZSkgDQogICAgaWQgPC0gaWRbb3JkZXIoY29sbmFtZXMoeCkpXQ0KICB0YWcudGFibGUgPC0gInRhYmxlIg0KICB0YWcudGhlYWQgPC0gInRoZWFkIg0KICB0YWcudGRhdGEgPC0gInRkYXRhIg0KICB0YWcuYXJjIDwtICJhcmMiDQogIHRhZy5jYXB0aW9uIDwtICJjYXB0aW9uIg0KICB0YWcub21pdCA8LSAib21pdCINCiAgY3NzLnRhYmxlIDwtICJib3JkZXItY29sbGFwc2U6Y29sbGFwc2U7IGJvcmRlcjpub25lOyINCiAgY3NzLnRoZWFkIDwtICJib3JkZXItYm90dG9tOmRvdWJsZTsgZm9udC1zdHlsZTppdGFsaWM7IGZvbnQtd2VpZ2h0Om5vcm1hbDsgcGFkZGluZzowLjJjbTsgdGV4dC1hbGlnbjpsZWZ0OyB2ZXJ0aWNhbC1hbGlnbjp0b3A7Ig0KICBjc3MudGRhdGEgPC0gInBhZGRpbmc6MC4yY207IHRleHQtYWxpZ246bGVmdDsgdmVydGljYWwtYWxpZ246dG9wOyINCiAgY3NzLmFyYyA8LSAiYmFja2dyb3VuZC1jb2xvcjojZWVlZWVlIg0KICBjc3MuY2FwdGlvbiA8LSAiZm9udC13ZWlnaHQ6IGJvbGQ7IHRleHQtYWxpZ246bGVmdDsiDQogIGNzcy5vbWl0IDwtICJjb2xvcjojOTk5OTk5OyINCiAgaWYgKCFpcy5udWxsKENTUykpIHsNCiAgICBpZiAoIWlzLm51bGwoQ1NTW1siY3NzLnRhYmxlIl1dKSkgDQogICAgICBjc3MudGFibGUgPC0gaWZlbHNlKHN1YnN0cmluZyhDU1NbWyJjc3MudGFibGUiXV0sIA0KICAgICAgICAxLCAxKSA9PSAiKyIsIHBhc3RlMChjc3MudGFibGUsIHN1YnN0cmluZyhDU1NbWyJjc3MudGFibGUiXV0sIA0KICAgICAgICAyKSksIENTU1tbImNzcy50YWJsZSJdXSkNCiAgICBpZiAoIWlzLm51bGwoQ1NTW1siY3NzLnRoZWFkIl1dKSkgDQogICAgICBjc3MudGhlYWQgPC0gaWZlbHNlKHN1YnN0cmluZyhDU1NbWyJjc3MudGhlYWQiXV0sIA0KICAgICAgICAxLCAxKSA9PSAiKyIsIHBhc3RlMChjc3MudGhlYWQsIHN1YnN0cmluZyhDU1NbWyJjc3MudGhlYWQiXV0sIA0KICAgICAgICAyKSksIENTU1tbImNzcy50aGVhZCJdXSkNCiAgICBpZiAoIWlzLm51bGwoQ1NTW1siY3NzLnRkYXRhIl1dKSkgDQogICAgICBjc3MudGRhdGEgPC0gaWZlbHNlKHN1YnN0cmluZyhDU1NbWyJjc3MudGRhdGEiXV0sIA0KICAgICAgICAxLCAxKSA9PSAiKyIsIHBhc3RlMChjc3MudGRhdGEsIHN1YnN0cmluZyhDU1NbWyJjc3MudGRhdGEiXV0sIA0KICAgICAgICAyKSksIENTU1tbImNzcy50ZGF0YSJdXSkNCiAgICBpZiAoIWlzLm51bGwoQ1NTW1siY3NzLmFyYyJdXSkpIA0KICAgICAgY3NzLmFyYyA8LSBpZmVsc2Uoc3Vic3RyaW5nKENTU1tbImNzcy5hcmMiXV0sIDEsIA0KICAgICAgICAxKSA9PSAiKyIsIHBhc3RlMChjc3MuYXJjLCBzdWJzdHJpbmcoQ1NTW1siY3NzLmFyYyJdXSwgDQogICAgICAgIDIpKSwgQ1NTW1siY3NzLmFyYyJdXSkNCiAgICBpZiAoIWlzLm51bGwoQ1NTW1siY3NzLmNhcHRpb24iXV0pKSANCiAgICAgIGNzcy5jYXB0aW9uIDwtIGlmZWxzZShzdWJzdHJpbmcoQ1NTW1siY3NzLmNhcHRpb24iXV0sIA0KICAgICAgICAxLCAxKSA9PSAiKyIsIHBhc3RlMChjc3MuY2FwdGlvbiwgc3Vic3RyaW5nKENTU1tbImNzcy5jYXB0aW9uIl1dLCANCiAgICAgICAgMikpLCBDU1NbWyJjc3MuY2FwdGlvbiJdXSkNCiAgICBpZiAoIWlzLm51bGwoQ1NTW1siY3NzLm9taXQiXV0pKSANCiAgICAgIGNzcy5vbWl0IDwtIGlmZWxzZShzdWJzdHJpbmcoQ1NTW1siY3NzLm9taXQiXV0sIA0KICAgICAgICAxLCAxKSA9PSAiKyIsIHBhc3RlMChjc3Mub21pdCwgc3Vic3RyaW5nKENTU1tbImNzcy5vbWl0Il1dLCANCiAgICAgICAgMikpLCBDU1NbWyJjc3Mub21pdCJdXSkNCiAgfQ0KICBwYWdlLnN0eWxlIDwtIHNwcmludGYoIjxzdHlsZT5cbmh0bWwsIGJvZHkgeyBiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZTsgfVxuJXMgeyAlcyB9XG4uJXMgeyAlcyB9XG4uJXMgeyAlcyB9XG4uJXMgeyAlcyB9XG4lcyB7ICVzIH1cbi4lcyB7ICVzIH1cbjwvc3R5bGU+IiwgDQogICAgdGFnLnRhYmxlLCBjc3MudGFibGUsIHRhZy50aGVhZCwgY3NzLnRoZWFkLCB0YWcudGRhdGEsIA0KICAgIGNzcy50ZGF0YSwgdGFnLmFyYywgY3NzLmFyYywgdGFnLmNhcHRpb24sIGNzcy5jYXB0aW9uLCANCiAgICB0YWcub21pdCwgY3NzLm9taXQpDQogIHRvV3JpdGUgPC0gc3ByaW50ZigiPGh0bWw+XG48aGVhZD5cbjxtZXRhIGh0dHAtZXF1aXY9XCJDb250ZW50LXR5cGVcIiBjb250ZW50PVwidGV4dC9odG1sO2NoYXJzZXQ9JXNcIj5cbiVzXG48L2hlYWQ+XG48Ym9keT5cbiIsIA0KICAgIGVuY29kaW5nLCBwYWdlLnN0eWxlKQ0KICBwYWdlLmNvbnRlbnQgPC0gc3ByaW50ZigiPHRhYmxlPlxuICA8Y2FwdGlvbj5EYXRhIGZyYW1lOiAlczwvY2FwdGlvbj5cbiIsIA0KICAgIGRlcGFyc2Uoc3Vic3RpdHV0ZSh4KSkpDQogIHBhZ2UuY29udGVudCA8LSBwYXN0ZTAocGFnZS5jb250ZW50LCAiICA8dHI+XG4gICAgIikNCiAgaWYgKHNob3cuaWQpIA0KICAgIHBhZ2UuY29udGVudCA8LSBwYXN0ZTAocGFnZS5jb250ZW50LCAiPHRoIGNsYXNzPVwidGhlYWRcIj5JRDwvdGg+IikNCiAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsICI8dGggY2xhc3M9XCJ0aGVhZFwiPk5hbWU8L3RoPiIpDQogIGlmIChzaG93LnR5cGUpIA0KICAgIHBhZ2UuY29udGVudCA8LSBwYXN0ZTAocGFnZS5jb250ZW50LCAiPHRoIGNsYXNzPVwidGhlYWRcIj5UeXBlPC90aD4iKQ0KICBwYWdlLmNvbnRlbnQgPC0gcGFzdGUwKHBhZ2UuY29udGVudCwgIjx0aCBjbGFzcz1cInRoZWFkXCI+TGFiZWw8L3RoPiIpDQogIGlmIChzaG93Lm5hKSANCiAgICBwYWdlLmNvbnRlbnQgPC0gcGFzdGUwKHBhZ2UuY29udGVudCwgIjx0aCBjbGFzcz1cInRoZWFkXCI+bWlzc2luZ3M8L3RoPiIpDQogIGlmIChzaG93LnZhbHVlcykgDQogICAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsICI8dGggY2xhc3M9XCJ0aGVhZFwiPlZhbHVlczwvdGg+IikNCiAgaWYgKHNob3cubGFiZWxzKSANCiAgICBwYWdlLmNvbnRlbnQgPC0gcGFzdGUwKHBhZ2UuY29udGVudCwgIjx0aCBjbGFzcz1cInRoZWFkXCI+VmFsdWUgTGFiZWxzPC90aD4iKQ0KICBpZiAoc2hvdy5mcnEpIA0KICAgIHBhZ2UuY29udGVudCA8LSBwYXN0ZTAocGFnZS5jb250ZW50LCAiPHRoIGNsYXNzPVwidGhlYWRcIj5GcmVxLjwvdGg+IikNCiAgaWYgKHNob3cucHJjKSANCiAgICBwYWdlLmNvbnRlbnQgPC0gcGFzdGUwKHBhZ2UuY29udGVudCwgIjx0aCBjbGFzcz1cInRoZWFkXCI+JTwvdGg+IikNCiAgaWYgKHNob3cud3RkLmZycSkgDQogICAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsICI8dGggY2xhc3M9XCJ0aGVhZFwiPndlaWdodGVkIEZyZXEuPC90aD4iKQ0KICBpZiAoc2hvdy53dGQucHJjKSANCiAgICBwYWdlLmNvbnRlbnQgPC0gcGFzdGUwKHBhZ2UuY29udGVudCwgIjx0aCBjbGFzcz1cInRoZWFkXCI+d2VpZ2h0ZWQgJTwvdGg+IikNCiAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsICJcbiAgPC90cj5cbiIpDQogIGlmICghaGlkZS5wcm9ncmVzcykgDQogICAgcGIgPC0gdXRpbHM6OnR4dFByb2dyZXNzQmFyKG1pbiA9IDAsIG1heCA9IGNvbGNudCwgc3R5bGUgPSAzKQ0KICBmb3IgKGNjbnQgaW4gc2VxX2xlbihjb2xjbnQpKSB7DQogICAgaW5kZXggPC0gaWRbY2NudF0NCiAgICBhcmNzdHJpbmcgPC0gIiINCiAgICBpZiAoYWx0ci5yb3cuY29sKSANCiAgICAgIGFyY3N0cmluZyA8LSBpZmVsc2Uoc2ptaXNjOjppc19ldmVuKGNjbnQpLCAiIGFyYyIsIA0KICAgICAgICAiIikNCiAgICBwYWdlLmNvbnRlbnQgPC0gcGFzdGUwKHBhZ2UuY29udGVudCwgIiAgPHRyPlxuIikNCiAgICBpZiAoc2hvdy5pZCkgDQogICAgICBwYWdlLmNvbnRlbnQgPC0gcGFzdGUwKHBhZ2UuY29udGVudCwgc3ByaW50ZigiICAgIDx0ZCBjbGFzcz1cInRkYXRhJXNcIj4laTwvdGQ+XG4iLCANCiAgICAgICAgYXJjc3RyaW5nLCBpbmRleCkpDQogICAgaWYgKCFpcy5saXN0KHhbW2luZGV4XV0pICYmICFpcy5udWxsKHNqbGFiZWxsZWQ6OmdldF9ub3RlKHhbW2luZGV4XV0pKSkgDQogICAgICB0ZC50aXRsZS50YWcgPC0gc3ByaW50ZigiIHRpdGxlPVwiJXNcIiIsIHNqbGFiZWxsZWQ6OmdldF9ub3RlKHhbW2luZGV4XV0pKQ0KICAgIGVsc2UgdGQudGl0bGUudGFnIDwtICIiDQogICAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsIHNwcmludGYoIiAgICA8dGQgY2xhc3M9XCJ0ZGF0YSVzXCIlcz4lczwvdGQ+XG4iLCANCiAgICAgIGFyY3N0cmluZywgdGQudGl0bGUudGFnLCBjb2xuYW1lcyh4KVtpbmRleF0pKQ0KICAgIGlmIChzaG93LnR5cGUpIHsNCiAgICAgIHZhcnR5cGUgPC0gc2ptaXNjOjp2YXJfdHlwZSh4W1tpbmRleF1dKQ0KICAgICAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsIHNwcmludGYoIiAgICA8dGQgY2xhc3M9XCJ0ZGF0YSVzXCI+JXM8L3RkPlxuIiwgDQogICAgICAgIGFyY3N0cmluZywgdmFydHlwZSkpDQogICAgfQ0KICAgIGlmIChpbmRleCA8PSBsZW5ndGgoZGYudmFyKSkgew0KICAgICAgdmFybGFiIDwtIGRmLnZhcltpbmRleF0NCiAgICAgIGlmICghaXMubnVsbCh3cmFwLmxhYmVscykpIHsNCiAgICAgICAgdmFybGFiIDwtIHNqbWlzYzo6d29yZF93cmFwKHZhcmxhYiwgd3JhcC5sYWJlbHMsIA0KICAgICAgICAgICI8YnI+IikNCiAgICAgIH0NCiAgICB9DQogICAgZWxzZSB7DQogICAgICB2YXJsYWIgPC0gIjxOQT4iDQogICAgfQ0KICAgIHBhZ2UuY29udGVudCA8LSBwYXN0ZTAocGFnZS5jb250ZW50LCBzcHJpbnRmKCIgICAgPHRkIGNsYXNzPVwidGRhdGElc1wiPiVzPC90ZD5cbiIsIA0KICAgICAgYXJjc3RyaW5nLCB2YXJsYWIpKQ0KICAgIGlmIChzaG93Lm5hKSB7DQogICAgICBpZiAoaXMubGlzdCh4W1tpbmRleF1dKSkgew0KICAgICAgICBwYWdlLmNvbnRlbnQgPC0gcGFzdGUwKHBhZ2UuY29udGVudCwgc3ByaW50ZigiICAgIDx0ZCBjbGFzcz1cInRkYXRhJXNcIj48c3BhbiBjbGFzcz1cIm9taXRcIj4mbHQ7bGlzdCZndDs8L3NwYW4+PC90ZD5cbiIsIA0KICAgICAgICAgIGFyY3N0cmluZykpDQogICAgICB9DQogICAgICBlbHNlIHsNCiAgICAgICAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsIHNwcmludGYoIiAgICA8dGQgY2xhc3M9XCJ0ZGF0YSVzXCI+JWkgKCUuMmYlJSk8L3RkPlxuIiwgDQogICAgICAgICAgYXJjc3RyaW5nLCBzdW0oaXMubmEoeFtbaW5kZXhdXSksIG5hLnJtID0gVCksIA0KICAgICAgICAgIDEwMCAqIHN1bShpcy5uYSh4W1tpbmRleF1dKSwgbmEucm0gPSBUKS9ucm93KHgpKSkNCiAgICAgIH0NCiAgICB9DQogICAgaWYgKGlzLm51bWVyaWMoeFtbaW5kZXhdXSkgJiYgIWhhc192YWx1ZV9sYWJlbHMoeFtbaW5kZXhdXSkpIHsNCiAgICAgIGlmIChzaG93LnZhbHVlcyB8fCBzaG93LmxhYmVscykgew0KICAgICAgICB2YWxzdHJpbmcgPC0gcGFzdGUwKHNwcmludGYoIiVhIiwgcmFuZ2UoeFtbaW5kZXhdXSwgDQogICAgICAgICAgbmEucm0gPSBUKSksIGNvbGxhcHNlID0gIi0iKQ0KICAgICAgICBpZiAoc2hvdy52YWx1ZXMgJiYgc2hvdy5sYWJlbHMpIHsNCiAgICAgICAgICBjb2xzcCA8LSAiIGNvbHNwYW49XCIyXCIiDQogICAgICAgICAgdmFsc3RyaW5nIDwtIHBhc3RlMCgiPGVtPnJhbmdlOiAiLCB2YWxzdHJpbmcsIA0KICAgICAgICAgICAgIjwvZW0+IikNCiAgICAgICAgfQ0KICAgICAgICBlbHNlIHsNCiAgICAgICAgICBjb2xzcCA8LSAiIg0KICAgICAgICB9DQogICAgICAgIHBhZ2UuY29udGVudCA8LSBwYXN0ZTAocGFnZS5jb250ZW50LCBzcHJpbnRmKCIgICAgPHRkIGNsYXNzPVwidGRhdGElc1wiJXM+JXM8L3RkPlxuIiwgDQogICAgICAgICAgYXJjc3RyaW5nLCBjb2xzcCwgdmFsc3RyaW5nKSkNCiAgICAgIH0NCiAgICB9DQogICAgZWxzZSB7DQogICAgICBpZiAoc2hvdy52YWx1ZXMpIHsNCiAgICAgICAgdmFsc3RyaW5nIDwtICIiDQogICAgICAgIGlmIChpbmRleCA8PSBuY29sKHgpKSB7DQogICAgICAgICAgaWYgKGlzLmxpc3QoeFtbaW5kZXhdXSkpIHsNCiAgICAgICAgICAgIHZhbHN0cmluZyA8LSAiPHNwYW4gY2xhc3M9XCJvbWl0XCI+Jmx0O2xpc3QmZ3Q7PC9zcGFuPiINCiAgICAgICAgICB9DQogICAgICAgICAgZWxzZSB7DQogICAgICAgICAgICB2YWxzIDwtIHNqbGFiZWxsZWQ6OmdldF92YWx1ZXMoeFtbaW5kZXhdXSkNCiAgICAgICAgICAgIGlmICghaXMubnVsbCh2YWxzKSkgew0KICAgICAgICAgICAgICBsb29wIDwtIG5hLm9taXQoc2VxX2xlbihsZW5ndGgodmFscykpWzE6bWF4Lmxlbl0pDQogICAgICAgICAgICAgIGZvciAoaSBpbiBsb29wKSB7DQogICAgICAgICAgICAgICAgdmFsc3RyaW5nIDwtIHBhc3RlMCh2YWxzdHJpbmcsIHZhbHNbaV0pDQogICAgICAgICAgICAgICAgaWYgKGkgPCBsZW5ndGgodmFscykpIA0KICAgICAgICAgICAgICAgICAgdmFsc3RyaW5nIDwtIHBhc3RlMCh2YWxzdHJpbmcsICI8YnI+IikNCiAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICBpZiAobWF4LmxlbiA8IGxlbmd0aCh2YWxzKSkgDQogICAgICAgICAgICAgICAgdmFsc3RyaW5nIDwtIHBhc3RlMCh2YWxzdHJpbmcsICI8c3BhbiBjbGFzcz1cIm9taXRcIj4mbHQ7Li4uJmd0Ozwvc3Bhbj4iKQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICBlbHNlIHsNCiAgICAgICAgICB2YWxzdHJpbmcgPC0gIjxOQT4iDQogICAgICAgIH0NCiAgICAgICAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsIHNwcmludGYoIiAgICA8dGQgY2xhc3M9XCJ0ZGF0YSVzXCI+JXM8L3RkPlxuIiwgDQogICAgICAgICAgYXJjc3RyaW5nLCB2YWxzdHJpbmcpKQ0KICAgICAgfQ0KICAgICAgaWYgKHNob3cubGFiZWxzKSB7DQogICAgICAgIHZhbHN0cmluZyA8LSAiIg0KICAgICAgICBpZiAoaW5kZXggPD0gbGVuZ3RoKGRmLnZhbCkpIHsNCiAgICAgICAgICBpZiAoaXMubGlzdCh4W1tpbmRleF1dKSkgew0KICAgICAgICAgICAgdmFsc3RyaW5nIDwtICI8c3BhbiBjbGFzcz1cIm9taXRcIj4mbHQ7bGlzdCZndDs8L3NwYW4+Ig0KICAgICAgICAgIH0NCiAgICAgICAgICBlbHNlIHsNCiAgICAgICAgICAgIHZhbHMgPC0gZGYudmFsW1tpbmRleF1dDQogICAgICAgICAgICBpZiAoIWlzLm51bGwodmFscykpIA0KICAgICAgICAgICAgICB2YWxzIDwtIG5hLm9taXQodmFscykNCiAgICAgICAgICAgIGlmIChpcy5jaGFyYWN0ZXIoeFtbaW5kZXhdXSkgJiYgIWlzLm51bGwodmFscykgJiYgDQogICAgICAgICAgICAgICFzam1pc2M6OmlzX2VtcHR5KHZhbHMpKSB7DQogICAgICAgICAgICAgIGlmIChzaG93LnN0cmluZy52YWx1ZXMpIA0KICAgICAgICAgICAgICAgIHZhbHMgPC0gc29ydCh2YWxzKQ0KICAgICAgICAgICAgICBlbHNlIHZhbHMgPC0gIjxzcGFuIGNsYXNzPVwib21pdFwiIHRpdGxlID1cIidzaG93LnN0cmluZy52YWx1ZXMgPSBUUlVFJyB0byBzaG93IHZhbHVlcy5cIj4mbHQ7b3V0cHV0IG9taXR0ZWQmZ3Q7PC9zcGFuPiINCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmICghaXMubnVsbCh2YWxzKSkgew0KICAgICAgICAgICAgICBsb29wIDwtIG5hLm9taXQoc2VxX2xlbihsZW5ndGgodmFscykpWzE6bWF4Lmxlbl0pDQogICAgICAgICAgICAgIGZvciAoaSBpbiBsb29wKSB7DQogICAgICAgICAgICAgICAgdmFsc3RyaW5nIDwtIHBhc3RlMCh2YWxzdHJpbmcsIHZhbHNbaV0pDQogICAgICAgICAgICAgICAgaWYgKGkgPCBsZW5ndGgodmFscykpIA0KICAgICAgICAgICAgICAgICAgdmFsc3RyaW5nIDwtIHBhc3RlMCh2YWxzdHJpbmcsICI8YnI+IikNCiAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICBpZiAobWF4LmxlbiA8IGxlbmd0aCh2YWxzKSkgDQogICAgICAgICAgICAgICAgdmFsc3RyaW5nIDwtIHBhc3RlMCh2YWxzdHJpbmcsICI8c3BhbiBjbGFzcz1cIm9taXRcIj4mbHQ7Li4uIHRydW5jYXRlZCZndDs8L3NwYW4+IikNCiAgICAgICAgICAgIH0NCiAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgZWxzZSB7DQogICAgICAgICAgdmFsc3RyaW5nIDwtICI8TkE+Ig0KICAgICAgICB9DQogICAgICAgIHBhZ2UuY29udGVudCA8LSBwYXN0ZTAocGFnZS5jb250ZW50LCBzcHJpbnRmKCIgICAgPHRkIGNsYXNzPVwidGRhdGElc1wiPiVzPC90ZD5cbiIsIA0KICAgICAgICAgIGFyY3N0cmluZywgdmFsc3RyaW5nKSkNCiAgICAgIH0NCiAgICB9DQogICAgaWYgKHNob3cuZnJxKSB7DQogICAgICBpZiAoaXMubGlzdCh4W1tpbmRleF1dKSkgDQogICAgICAgIHZhbHN0cmluZyA8LSAiPHNwYW4gY2xhc3M9XCJvbWl0XCI+Jmx0O2xpc3QmZ3Q7PC9zcGFuPiINCiAgICAgIGVsc2UgdmFsc3RyaW5nIDwtIGZycS52YWx1ZShpbmRleCwgeCwgZGYudmFsKQ0KICAgICAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsIHNwcmludGYoIiAgICA8dGQgY2xhc3M9XCJ0ZGF0YSVzXCI+JXM8L3RkPlxuIiwgDQogICAgICAgIGFyY3N0cmluZywgdmFsc3RyaW5nKSkNCiAgICB9DQogICAgaWYgKHNob3cucHJjKSB7DQogICAgICBpZiAoaXMubGlzdCh4W1tpbmRleF1dKSkgDQogICAgICAgIHZhbHN0cmluZyA8LSAiPHNwYW4gY2xhc3M9XCJvbWl0XCI+Jmx0O2xpc3QmZ3Q7PC9zcGFuPiINCiAgICAgIGVsc2UgdmFsc3RyaW5nIDwtIHByYy52YWx1ZShpbmRleCwgeCwgZGYudmFsKQ0KICAgICAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsIHNwcmludGYoIiAgICA8dGQgY2xhc3M9XCJ0ZGF0YSVzXCI+JXM8L3RkPlxuIiwgDQogICAgICAgIGFyY3N0cmluZywgdmFsc3RyaW5nKSkNCiAgICB9DQogICAgaWYgKHNob3cud3RkLmZycSAmJiAhaXMubnVsbCh3ZWlnaHQuYnkpKSB7DQogICAgICBpZiAoaXMubGlzdCh4W1tpbmRleF1dKSkgDQogICAgICAgIHZhbHN0cmluZyA8LSAiPHNwYW4gY2xhc3M9XCJvbWl0XCI+Jmx0O2xpc3QmZ3Q7PC9zcGFuPiINCiAgICAgIGVsc2UgdmFsc3RyaW5nIDwtIGZycS52YWx1ZShpbmRleCwgeCwgZGYudmFsLCB3ZWlnaHQuYnkpDQogICAgICBwYWdlLmNvbnRlbnQgPC0gcGFzdGUwKHBhZ2UuY29udGVudCwgc3ByaW50ZigiICAgIDx0ZCBjbGFzcz1cInRkYXRhJXNcIj4lczwvdGQ+XG4iLCANCiAgICAgICAgYXJjc3RyaW5nLCB2YWxzdHJpbmcpKQ0KICAgIH0NCiAgICBpZiAoc2hvdy5wcmMgJiYgIWlzLm51bGwod2VpZ2h0LmJ5KSkgew0KICAgICAgaWYgKGlzLmxpc3QoeFtbaW5kZXhdXSkpIA0KICAgICAgICB2YWxzdHJpbmcgPC0gIjxzcGFuIGNsYXNzPVwib21pdFwiPiZsdDtsaXN0Jmd0Ozwvc3Bhbj4iDQogICAgICBlbHNlIHZhbHN0cmluZyA8LSBwcmMudmFsdWUoaW5kZXgsIHgsIGRmLnZhbCwgd2VpZ2h0LmJ5KQ0KICAgICAgcGFnZS5jb250ZW50IDwtIHBhc3RlMChwYWdlLmNvbnRlbnQsIHNwcmludGYoIiAgICA8dGQgY2xhc3M9XCJ0ZGF0YSVzXCI+JXM8L3RkPlxuIiwgDQogICAgICAgIGFyY3N0cmluZywgdmFsc3RyaW5nKSkNCiAgICB9DQogICAgaWYgKCFoaWRlLnByb2dyZXNzKSANCiAgICAgIHV0aWxzOjpzZXRUeHRQcm9ncmVzc0JhcihwYiwgY2NudCkNCiAgICBwYWdlLmNvbnRlbnQgPC0gcGFzdGUwKHBhZ2UuY29udGVudCwgIiAgPC90cj5cbiIpDQogIH0NCiAgaWYgKCFoaWRlLnByb2dyZXNzKSANCiAgICBjbG9zZShwYikNCiAgcGFnZS5jb250ZW50IDwtIHBhc3RlKHBhZ2UuY29udGVudCwgIjwvdGFibGU+Iiwgc2VwID0gIlxuIikNCiAgdG9Xcml0ZSA8LSBwYXN0ZTAodG9Xcml0ZSwgc3ByaW50ZigiJXNcbjwvYm9keT48L2h0bWw+IiwgDQogICAgcGFnZS5jb250ZW50KSkNCiAga25pdHIgPC0gcGFnZS5jb250ZW50DQogIGtuaXRyIDwtIGdzdWIoImNsYXNzPSIsICJzdHlsZT0iLCBrbml0ciwgZml4ZWQgPSBUUlVFLCB1c2VCeXRlcyA9IFRSVUUpDQogIGtuaXRyIDwtIGdzdWIoIjx0YWJsZSIsIHNwcmludGYoIjx0YWJsZSBzdHlsZT1cIiVzXCIiLCBjc3MudGFibGUpLCANCiAgICBrbml0ciwgZml4ZWQgPSBUUlVFLCB1c2VCeXRlcyA9IFRSVUUpDQogIGtuaXRyIDwtIGdzdWIodGFnLnRkYXRhLCBjc3MudGRhdGEsIGtuaXRyLCBmaXhlZCA9IFRSVUUsIA0KICAgIHVzZUJ5dGVzID0gVFJVRSkNCiAga25pdHIgPC0gZ3N1Yih0YWcudGhlYWQsIGNzcy50aGVhZCwga25pdHIsIGZpeGVkID0gVFJVRSwgDQogICAgdXNlQnl0ZXMgPSBUUlVFKQ0KICBrbml0ciA8LSBnc3ViKHRhZy5hcmMsIGNzcy5hcmMsIGtuaXRyLCBmaXhlZCA9IFRSVUUsIHVzZUJ5dGVzID0gVFJVRSkNCiAgaWYgKHJlbW92ZS5zcGFjZXMpIHsNCiAgICBrbml0ciA8LSBzanUucm1zcGMoa25pdHIpDQogICAgdG9Xcml0ZSA8LSBzanUucm1zcGModG9Xcml0ZSkNCiAgICBwYWdlLmNvbnRlbnQgPC0gc2p1LnJtc3BjKHBhZ2UuY29udGVudCkNCiAgfQ0KICBzdHJ1Y3R1cmUoY2xhc3MgPSBjKCJzalRhYmxlIiwgInZpZXdfZGYiKSwgbGlzdChwYWdlLnN0eWxlID0gcGFnZS5zdHlsZSwgDQogICAgcGFnZS5jb250ZW50ID0gcGFnZS5jb250ZW50LCBvdXRwdXQuY29tcGxldGUgPSB0b1dyaXRlLCANCiAgICBoZWFkZXIgPSBOVUxMLCBrbml0ciA9IGtuaXRyLCBmaWxlID0gZmlsZSwgc2hvdyA9ICFuby5vdXRwdXQsIA0KICAgIHVzZS52aWV3ZXIgPSB1c2Uudmlld2VyKSkNCn0NCg0Kdmlld19kZjIoYXJhYjQsIGhpZGUucHJvZ3Jlc3MgPSBUKQ0KYGBgDQoNCg0K